根据我在网上阅读的内容,很难理解sed
.我对看似懒惰的匹配感到困惑。
在 中~/tmp/tmp.txt
,我有一行包含 3 个字母数字字符串,并用 2 个制表符分隔:TheQuick<TAB>BrownFox<TAB>JumpedOver
。如果我发出sed -n -E '/^.+\t.+\t.+$/p' ~/tmp/tmp.txt
,该行就会打印出来。
在我看来,它不应该,因为即使正则表达式匹配由 2 个制表符分隔的 3 个字符串,这些字符串也不是字母数字。因此,第一个字符串应该贪婪地吞噬该行上的所有字符,不留下任何与第一个选项卡匹配的内容。
我如何理解这种行为,以便我可以制作可靠的正则表达式?我正在使用 GNU sed
。
答案1
贪婪匹配系统只是意味着它会尝试找到最大的匹配字符串(意思是第一的最大,它将在整个正则表达式的第一个匹配处停止搜索),而不是即使存在匹配字符串,它也会在不匹配的字符串处停止。将其视为“为我找到最大可能的匹配项,但一定要为我找到匹配项!”的命令。由于允许第一个.\+
吃掉整个字符串意味着正则表达式不匹配,因此引擎将返回并尝试其他操作。
在您的情况下,它甚至更简单,因为您将正则表达式锚定到行的开头和结尾(^
和$
),因此.+
永远无法到达行尾,因为正则表达式中还有其他内容。
这是一个可能有助于解释贪婪匹配的示例:
$ echo aaaaaaa | sed 's/a*/B/'
B
这里,由于正则表达式的a*
意思是“匹配0个或多个连续a
字符”,所以贪心匹配会找到最大可能的匹配细绳。非贪婪匹配(例如使用 PCRE)将返回:
$ echo aaaaaaa | perl -pe 's/a*?/B/'
Baaaaaaa
这是因为非贪婪会找到最短的匹配字符串而不是最长的。
我不明白你为什么提到字母数字或它有何相关性。也许您误解了.
并认为只匹配字母数字字符串,但事实并非如此;.
将匹配所有内容(取决于您使用的正则表达式的风格以及您提供的选项,它甚至可以匹配换行符)。如果您想要字母数字字符串,您可以使用[[:alnum:]]
匹配 的POSIX 字符类[a-zA-Z0-9]
。