regex - 使用 [] 的扩展正则表达式中的顺序是否重要?

标签 regex grep

我试图在 grep 中理解带有扩展正则表达式的 [] 语法。

下面两种模式是等价的:

$ echo "foo_bar" | grep -E "[a-z_]+$"     
foo_bar
$ echo "foo_bar" | grep -E "[_a-z]+$" 
foo_bar

然而,这两个不是:

$ echo "foobar[]" | grep -E "[a-z_\[\]]+$" 
foobar[]
$ echo "foobar[]" | grep -E "[a-z\[\]_]+$"

这是为什么?这在任何地方都有记录吗?我在 man grep 中看不到任何关于此的内容。

最佳答案

使用双引号 " 和反斜杠 \ 时要小心,因为 BASH 首先处理反斜杠。这会将正则表达式更改为 [a-z_[ ]]+$。不过,还有一点很好,对于这个问题的其余部分,我假设您使用了单引号。

在第一种情况下,您有字符组 [a-z_\[\],它匹配字符 a-z_\[。最后的 \] 没有将 ] 列为字符组的另一个字符,而是另一个 \ 和字符类的右括号.注意如何:

$ echo "foobar[]" | grep -E '[a-z\[\]+\]+$'
foobar[]
$ echo '\' | grep -E '[\]$'
\

如果你想添加]你必须先列出它,即[]]匹配单个]

$ echo "]" | grep -E '[]]$'
]

有关引用,请参阅 man grep:

To include a literal ] place it first in the list. Similarly, to include a literal ^ place it anywhere but first. Finally, to include a literal - place it last.

以及https://www.regular-expressions.info/charclass.html

In most regex flavors, the only special characters or metacharacters inside a character class are the closing bracket ], the backslash \, the caret ^, and the hyphen -. The usual metacharacters are normal characters inside a character class, and do not need to be escaped by a backslash. To search for a star or plus, use [+*]. Your regex will work fine if you escape the regular metacharacters inside a character class, but doing so significantly reduces readability.

更多的测试用例来检查 [\s](与 [s\] 相同,与 [[:space:]] 不同):

$ echo 'a ' | grep -E 'a[\s]$'
$ echo 's' | grep -E '[\s]$'
s
$ echo '\' | grep -E '[\s]$'
\
$ echo 'a ' | grep -E 'a[[:space:]]$'
a

所以要点是:在列出字符类的字符时,顺序无关紧要,除非它确实如此。

关于regex - 使用 [] 的扩展正则表达式中的顺序是否重要?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52938561/

相关文章:

regex - 使用正则表达式查找替换匹配 URI

regex - linux中使用diff awk grep和正则表达式获取最近添加的驱动器名称

Linux 查找文件和 grep 然后按日期列出

regex - Apache .htaccess 重定向带有阿拉伯字符的 URL

regex - sed 查找并用空格替换字符串

regex - 如何在 300GB .txt 文件上使用 awk 和 grep?

javascript - 如何使用正则表达式确保 `@` 旁边应该只有字母

linux - 在每一行的开头搜索

command-line - Silver-searcher 是否能够从文件中获取 PATTERN?

python - 根据特定模式将单个文本文件分成多个文件