【发布时间】:2010-09-19 18:16:31
【问题描述】:
我有以下文字
tooooooooooooon
根据我正在阅读的这本书,当? 跟在任何量词之后时,它变得不贪心。
我的正则表达式 to*?n 仍在返回 tooooooooooooon。
它应该返回ton 不是吗?
知道为什么吗?
【问题讨论】:
标签: regex regex-greedy non-greedy
我有以下文字
tooooooooooooon
根据我正在阅读的这本书,当? 跟在任何量词之后时,它变得不贪心。
我的正则表达式 to*?n 仍在返回 tooooooooooooon。
它应该返回ton 不是吗?
知道为什么吗?
【问题讨论】:
标签: regex regex-greedy non-greedy
Regex 总是尽力匹配。在这种情况下,您唯一要做的就是通过让解析器回溯到 /o*?/ 节点来减慢解析器的速度。 "tooooon" 中的每个 'o' 一次。而在正常匹配的情况下,第一次需要尽可能多的'o's。由于下一个要匹配的元素是'n',它不会被'o' 匹配,因此尝试使用最小匹配没有什么意义。实际上,当正常匹配失败时,它需要相当长的时间才能失败。它必须通过每个'o' 回溯,直到没有人可以回溯。在这种情况下,我实际上会使用最大匹配/to*+n/。 'o' 会尽其所能,永远不会退还任何东西。这将使它在失败时迅速失败。
(注意:Maximal RE 类似)
'太棒了' ~~ /to*n/ t o o o o o o o o o o o o {t} 匹配 [t] [t]{o}{o}{o}{o}{o}{o} 匹配 [o] 6 次 [t][o][o][o][o][o][o]{n} 匹配 [n]【讨论】:
正则表达式总是渴望匹配。
你的表情是这样说的:
一个“t”,后跟*尽可能少的*“o”,然后是一个“n”。这意味着任何必要的 o 都将被匹配,因为末尾有一个 'n',表达式渴望达到。匹配所有的o是成功的唯一可能。
【讨论】:
正则表达式尝试匹配其中的所有内容。因为要匹配的 'o' 不比匹配 n 的每个 o 少,所以一切都匹配。另外,因为您使用的是 o*?而不是 o+?您不需要在场。
示例,在 Perl 中
$a = "toooooo";
$b = "toooooon";
if ($a =~ m/(to*?)/) {
print $1,"\n";
}
if ($b =~ m/(to*?n)/) {
print $1,"\n";
}
~>perl ex.pl
t
toooooon
【讨论】:
正则表达式只能匹配实际存在的文本片段。
因为子字符串 'ton' 不存在于字符串中的任何位置,它不可能是匹配的结果。匹配只会返回原始字符串的子字符串
编辑:为了清楚起见,如果您使用下面的字符串,则带有一个额外的 'n'
toooooooonoooooon
这个正则表达式(不指定 'o's)
t.*n
将匹配以下内容(在“n”之前尽可能多的字符)
toooooooonoooooon
但是正则表达式
t.*?n
只会匹配以下内容(“n”之前的字符尽可能少)
toooooooon
【讨论】:
您正在搜索的字符串(实际上是大海捞针)不包含子字符串“ton”。
但它确实包含子字符串“tooooooooooooon”。
【讨论】: