Bug 287396 - grep(1): BSD grep \w matches differently from GNU grep
Summary: grep(1): BSD grep \w matches differently from GNU grep
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: bin (show other bugs)
Version: 14.3-RELEASE
Hardware: amd64 Any
: --- Affects Only Me
Assignee: Kyle Evans
URL:
Keywords:
Depends on: 218806
Blocks: 230332
  Show dependency treegraph
 
Reported: 2025-06-09 15:20 UTC by OHARA Shigeki
Modified: 2026-05-11 15:58 UTC (History)
4 users (show)

See Also:
kevans: mfc-stable14+


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description OHARA Shigeki 2025-06-09 15:20:40 UTC
It seems that the \w character class in BSD grep matches differently compared to GNU grep.
Specifically, GNU grep's \w matches the underscore (_), whereas BSD grep does not.
Is this behavior intentional?


admin@freebsd14:~ $ cat /etc/os-release
NAME=FreeBSD
VERSION="14.3-RELEASE"
VERSION_ID="14.3"
ID=freebsd
ANSI_COLOR="0;31"
PRETTY_NAME="FreeBSD 14.3-RELEASE"
CPE_NAME="cpe:/o:freebsd:freebsd:14.3"
HOME_URL="https://FreeBSD.org/"
BUG_REPORT_URL="https://bugs.FreeBSD.org/"
admin@freebsd14:~ $ echo $LANG
C.UTF-8
admin@freebsd14:~ $ grep --version
grep (BSD grep, GNU compatible) 2.6.0-FreeBSD
admin@freebsd14:~ $ echo a_ | grep -o '\w*'
a
admin@freebsd14:~ $ ggrep --version
ggrep (GNU grep) 3.11
Copyright (C) 2023 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Mike Haertel and others; see
<https://git.savannah.gnu.org/cgit/grep.git/tree/AUTHORS>.

grep -P uses PCRE2 10.45 2025-02-05
admin@freebsd14:~ $ echo a_ | ggrep -o '\w*'
a_
admin@freebsd14:~ $
Comment 1 Wolfram Schneider freebsd_committer freebsd_triage 2025-06-10 13:54:14 UTC
The cool kids use ripgrep or ugrep.

echo a_ | rg -o '\w*'
a_

echo a_ | ug -o '\w*'
     1:	_
Comment 2 Kyle Evans freebsd_committer freebsd_triage 2025-08-08 16:45:54 UTC
(In reply to OHARA Shigeki from comment #0)

We map \w to [[:alnum:]], and in the POSIX locale _ doesn't fit the bill (neither a `digit` nor a `alpha`).  I'm looking at the documentation[0] again, and I see now that it is explicitly alnum + _.  I will fix this.

[0] https://www.gnu.org/software/grep/manual/html_node/The-Backslash-Character-and-Special-Expressions.html
Comment 3 commit-hook freebsd_committer freebsd_triage 2025-08-08 18:28:56 UTC
A commit in branch main references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=d0ff5773cefaf3fa41b1be3e44ca35bd9d5f68ee

commit d0ff5773cefaf3fa41b1be3e44ca35bd9d5f68ee
Author:     Kyle Evans <kevans@FreeBSD.org>
AuthorDate: 2025-08-08 18:21:03 +0000
Commit:     Kyle Evans <kevans@FreeBSD.org>
CommitDate: 2025-08-08 18:27:26 +0000

    libregex: fix our mapping for \w

    A small oversight in our implementation of \w is that it's actually
    not strictly [[:alnum:]].  According to the GNU documentation, it's
    actually [[:alnum:]] + underscore.  The fix is rather trivial: just add
    it to our set explicitly, and amend our test set to be sure that _ is
    actually included.

    PR:             287396

 lib/libc/regex/regcomp.c     | 1 +
 lib/libregex/tests/gnuext.in | 6 +++---
 2 files changed, 4 insertions(+), 3 deletions(-)
Comment 4 Andre Albsmeier 2026-05-11 06:06:44 UTC
Can this be MFC'ed to 14, please?
Comment 5 commit-hook freebsd_committer freebsd_triage 2026-05-11 15:26:58 UTC
A commit in branch stable/14 references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=d64438a09dc8e466c969fbe94c1a2fa500554da4

commit d64438a09dc8e466c969fbe94c1a2fa500554da4
Author:     Kyle Evans <kevans@FreeBSD.org>
AuthorDate: 2025-08-08 18:21:03 +0000
Commit:     Kyle Evans <kevans@FreeBSD.org>
CommitDate: 2026-05-11 15:20:50 +0000

    libregex: fix our mapping for \w

    A small oversight in our implementation of \w is that it's actually
    not strictly [[:alnum:]].  According to the GNU documentation, it's
    actually [[:alnum:]] + underscore.  The fix is rather trivial: just add
    it to our set explicitly, and amend our test set to be sure that _ is
    actually included.

    PR:             287396
    (cherry picked from commit d0ff5773cefaf3fa41b1be3e44ca35bd9d5f68ee)

 lib/libc/regex/regcomp.c     | 1 +
 lib/libregex/tests/gnuext.in | 6 +++---
 2 files changed, 4 insertions(+), 3 deletions(-)
Comment 6 Kyle Evans freebsd_committer freebsd_triage 2026-05-11 15:27:30 UTC
(In reply to Andre Albsmeier from comment #4)

It is done, thanks for the reminder.
Comment 7 Andre Albsmeier 2026-05-11 15:34:31 UTC
Thanks for the quick MFC.

BTW, is there any documentation that we support the GNU extensions? I checked re_format(7), regex(3) and of course grep but didn't find anything.

In fact, I wasn't even aware of this until I created

https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=295191

today (and stumbled over \b which is used there)...
Comment 8 Kyle Evans freebsd_committer freebsd_triage 2026-05-11 15:58:53 UTC
(In reply to Andre Albsmeier from comment #7)

> BTW, is there any documentation that we support the GNU extensions? I checked
> re_format(7), regex(3) and of course grep but didn't find anything.

Not really (it's my fault), because support is still really sporadic- only grep(1) actually supports them (via libregex).  I wanted to switch sed(1) over as well, but iirc I hit a number of failures in an exp-run and then lost time to address those.