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