为什么“ [az] *”与非字母字符串匹配?


9

我有alphanum两行内容:

123 abc
this is a line

我对为什么在运行时sed 's/[a-z]*/SUB/' alphanum得到以下输出感到困惑:

SUB123 abc
SUB is a line

我期待:

123 SUB
SUB is a line

我找到了一个修复程序(sed 's/[a-z][a-z]*/SUB/'改用),但是我不明白为什么它起作用,而我的却不起作用。

你能帮我吗?



@Kamaraj,那是相似的,但是外壳模式与正则表达式混淆在最上面(答案集中在前者,因为那是ls foo*使用的)。但是无论如何,如果您发现重复的问题,我想您也应该将其标记为同样的问题。
ilkkachu

查看regexr.com上的实时图像并进行解释
-RozzA,

@RozzA请注意,您链接到的网站支持Javascript和Perl正则表达式,而不是POSIX正则表达式。
库萨兰达

Answers:


28

图案[a-z]*匹配零个的范围内或更多的字符a,以z(在实际的字符是依赖于当前的环境)。在字符串的开头123 abc(即模式匹配)有零个这样的字符,在开头有四个this is a line

如果您至少需要一个匹配,然后用[a-z][a-z]*[a-z]\{1,\},或启用扩展正则表达式与sed -E和使用[a-z]+

要显示模式匹配的位置,请在每个匹配项周围添加括号:

$ sed 's/[a-z]*/(&)/' file
()123 abc
(this) is a line

或者,查看所有匹配项:

$ sed 's/[a-z]*/(&)/g' file
()1()2()3() (abc)
(this) (is) (a) (line)

将最后结果与

$ sed -E 's/[a-z]+/(&)/g' file
123 (abc)
(this) (is) (a) (line)

7
从技术上讲,[a-z]匹配元素可以由多个字符组成。例如,在一些匈牙利语言环境,[a-z]匹配上dzs
斯特凡Chazelas

12

因为*匹配零个或多个先前原子的重复,所以所有正则表达式引擎都试图找到第一个匹配项。字符串的开头有一个完全为零个字母的子字符串,因此它与之匹配。如果字符串以字母开头,则*匹配尽可能多,但这仅次于最左边的匹配。

零长度匹配可能会有些问题,如您所见,解决方案是修改模式,使其至少需要一个字符。使用扩展的正则表达式,您可以+sed -E 's/[a-z]+/SUB/'

为了娱乐,请尝试:

echo 'less than 123 words' | sed 's/[0-9]*/x/g'
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.