我正试图通过扩展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
中我什么都看不到。
答案 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
因此,要点是:列出字符类的字符时顺序无关紧要,除非如此。