我有以下文字
tooooooooooooon
根据我正在阅读的这本书,当?
在任何量词之后跟随时,它变得非贪婪。
我的正则表达式to*?n
仍在返回tooooooooooooon
。
它应该返回ton
不应该吗?
知道为什么吗?
我有以下文字
tooooooooooooon
根据我正在阅读的这本书,当?
在任何量词之后跟随时,它变得非贪婪。
我的正则表达式to*?n
仍在返回tooooooooooooon
。
它应该返回ton
不应该吗?
知道为什么吗?
正则表达式只能匹配实际存在的文本片段。
因为子字符串 'ton' 在字符串中的任何位置都不存在,所以它不可能是匹配的结果。匹配只会返回原始字符串的子字符串
编辑:要清楚,如果您使用下面的字符串,带有额外的 'n'
toooooooonoooooon
此正则表达式(未指定 'o')
t.*n
将匹配以下内容(在“n”之前尽可能多的字符)
toooooooonoooooon
但是正则表达式
t.*?n
只会匹配以下内容(在“n”之前尽可能少的字符)
toooooooon
正则表达式 es 总是渴望匹配。
你的表情是这样说的:
一个“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
正则表达式总是尽力匹配。在这种情况下,您唯一要做的就是通过让解析器回溯到/o*?/
节点来减慢解析器的速度。中的每个单曲'o'
一次"tooooon"
。'o'
而对于普通匹配,第一次通过时会花费尽可能多的 s。由于要匹配的下一个元素是'n'
,它不会被 匹配'o'
,因此尝试使用最小匹配没有什么意义。实际上,当正常匹配失败时,它需要相当长的时间才能失败。它必须回溯每一个'o'
,直到没有任何东西可以回溯。在这种情况下,我实际上会使用最大匹配/to*+n/
。这'o'
会尽其所能,从不归还。这将使它在失败时迅速失败。
'toooooon' ~~ /to*?n/ 太棒了 {t} 匹配 [t] [t] 匹配 [o] 0 次 [t]<n> 匹配失败 [n] -> 重试 [o] [t]{o} 匹配 [o] 1 次 [t][o]<n> 匹配失败 [n] -> 重试 [o] [t][o]{o} 匹配 [o] 2 次 [t][o][o]<n> 匹配失败 [n] -> 重试 [o] . . . . [t][o][o][o][o]{o} 匹配 [o] 5 次 [t][o][o][o][o][o]<n> 匹配失败 [n] -> 重试 [o] [t][o][o][o][o][o]{o} 匹配 [o] 6 次 [t][o][o][o][o][o][o]{n} 匹配 [n]
(注意:Maximal RE 类似)
'太棒了' ~~ /to*n/ 太棒了 {t} 匹配 [t] [t]{o}{o}{o}{o}{o}{o} 匹配 [o] 6 次 [t][o][o][o][o][o][o]{n} 匹配 [n]
'toooooo' ~~ /to*?n/ 太棒了 . . . . . . . . [t][o][o][o][o]{o} 匹配 [o] 5 次 [t][o][o][o][o][o]<n> 匹配失败 [n] -> 重试 [o] [t][o][o][o][o][o]{o} 匹配 [o] 6 次 [t][o][o][o][o][o][o]<n> 匹配失败 [n] -> 重试 [o] [t][o][o][o][o][o][o]<o> 匹配失败 [o] 7 次 -> 匹配失败
'toooooo' ~~ /to*n/ 太棒了 {t} 匹配 [t] [t]{o}{o}{o}{o}{o}{o} 匹配 [o] 6 次 [t][o][o][o][o][o][o]<n> 匹配失败 [n] -> 重试 [o] [t][o][o][o][o][o] 匹配 [o] 5 次 [t][o][o][o][o][o]<n> 匹配失败 [n] -> 重试 [o] . . . . [t][o] 匹配 [o] 1 次 [t][o]<o> 匹配失败 [n] -> 重试 [o] [t] 匹配 [o] 0 次 [t]<n> 匹配失败 [n] -> 匹配失败
'toooooo' ~~ /to*+n/ 太棒了 {t} 匹配 [t] [t]{o}{o}{o}{o}{o}{o} 匹配 [o] 6 次 [t][o][o][o][o][o][o]<n> 匹配失败 [n] -> 匹配失败
您正在搜索的字符串(就像是大海捞针)不包含子字符串“ton”。
然而,它确实包含子字符串“tooooooooooooon”。