我有以下文字
tooooooooooooon
根据我正在阅读的这本书,当?
跟随任何量词之后,它变得非贪婪。
我的正则表达式to*?n
仍在返回tooooooooooooon
。
它应该返回ton
不应该吗?
知道为什么吗?
答案 0 :(得分:46)
正则表达式只能匹配实际存在的文本片段。
因为子字符串'ton'不存在于字符串中的任何位置,所以它不能是匹配的结果。匹配只返回原始字符串的子字符串
编辑:要清楚,如果您使用下面的字符串,请使用额外的'n'
toooooooonoooooon
这个正则表达式(没有指定'o')
t.*n
将匹配以下内容(在'n'之前尽可能多的字符)
toooooooonoooooon
但是正则表达式
t.*?n
只会匹配以下内容(在'n'之前尽可能少的字符)
toooooooon
答案 1 :(得分:5)
正则表达式总是渴望匹配。
你的表达是这样说的:
A 't', followed by *as few as possible* 'o's, followed by a 'n'.
这意味着任何必要的匹配都会匹配,因为结尾有一个'n',表达式很想达到。匹配所有o是唯一成功的可能性。
答案 2 :(得分:4)
Regexps尝试匹配其中的所有内容。因为与太阳中的每个o匹配并没有比匹配n更少的'o',所以一切都匹配。另外,因为你正在使用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
答案 3 :(得分:4)
正则表达式总是尽力匹配。在这种情况下,您唯一要做的就是通过让解析器回溯到/o*?/
节点来减慢解析器的速度。 'o'
中的每个"tooooon"
一次。然而,通过正常匹配,第一次通过时,可能需要尽可能多的'o'
s。由于要匹配的下一个元素是'n'
,'o'
不匹配,因此尝试使用最小匹配几乎没有意义。实际上,当正常匹配失败时,它将需要很长时间才能失败。它必须回溯每个'o'
,直到没有任何东西可以回溯。在这种情况下,我实际上会使用最大匹配/to*+n/
。 'o'
将尽其所能,并且永远不会给予任何回报。这将使它在失败时迅速失败。
'toooooon' ~~ /to*?n/ t o o o o o o n {t} match [t] [t] match [o] 0 times [t]<n> fail to match [n] -> retry [o] [t]{o} match [o] 1 times [t][o]<n> fail to match [n] -> retry [o] [t][o]{o} match [o] 2 times [t][o][o]<n> fail to match [n] -> retry [o] . . . . [t][o][o][o][o]{o} match [o] 5 times [t][o][o][o][o][o]<n> fail to match [n] -> retry [o] [t][o][o][o][o][o]{o} match [o] 6 times [t][o][o][o][o][o][o]{n} match [n]
(注意:类似于Maximal RE)
'toooooon' ~~ /to*n/ t o o o o o o n {t} match [t] [t]{o}{o}{o}{o}{o}{o} match [o] 6 times [t][o][o][o][o][o][o]{n} match [n]
'toooooo' ~~ /to*?n/ t o o o o o o . . . . . . . . [t][o][o][o][o]{o} match [o] 5 times [t][o][o][o][o][o]<n> fail to match [n] -> retry [o] [t][o][o][o][o][o]{o} match [o] 6 times [t][o][o][o][o][o][o]<n> fail to match [n] -> retry [o] [t][o][o][o][o][o][o]<o> fail to match [o] 7 times -> match failed
'toooooo' ~~ /to*n/ t o o o o o o {t} match [t] [t]{o}{o}{o}{o}{o}{o} match [o] 6 times [t][o][o][o][o][o][o]<n> fail to match [n] -> retry [o] [t][o][o][o][o][o] match [o] 5 times [t][o][o][o][o][o]<n> fail to match [n] -> retry [o] . . . . [t][o] match [o] 1 times [t][o]<o> fail to match [n] -> retry [o] [t] match [o] 0 times [t]<n> fail to match [n] -> match failed
'toooooo' ~~ /to*+n/ t o o o o o o {t} match [t] [t]{o}{o}{o}{o}{o}{o} match [o] 6 times [t][o][o][o][o][o][o]<n> fail to match [n] -> match failed
答案 4 :(得分:2)
您正在搜索的字符串(干草堆原样)不包含子字符串“ton”。
但它包含子字符串“tooooooooooooon”。