顺序对带有[]的扩展正则表达式有影响吗?

时间:2018-10-22 22:27:32

标签: 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中我什么都看不到。

1 个答案:

答案 0 :(得分:2)

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

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

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

如果要添加],则必须首先列出它,即[]]与单个]匹配。

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

有关参考,请参见man grep

  

要包含文字],请将其放在列表的第一位。同样,要包含文字^,请将其放置在除第一个以外的任何位置。最后,要包含文字,请放在最后。

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

  

在大多数正则表达式中,字符类中唯一的特殊字符或元字符是右括号[],反斜杠\,脱字符^和连字符-。通常的元字符是字符类中的普通字符,不需要用反斜杠转义。要搜索星号或加号,请使用[+ *]。如果您转义字符类中的常规元字符,则您的正则表达式可以正常工作,但这样做会大大降低可读性。

甚至有更多测试用例来检查[\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

因此,要点是:列出字符类的字符时顺序无关紧要,除非如此。