我发现,非贪婪的regex匹配只有当锚定在前面,而不是最后才变成非贪婪的:
$ echo abcabcabc | perl -ne 'print $1 if /^(a.*c)/'
abcabcabc
# OK, greedy match
$ echo abcabcabc | perl -ne 'print $1 if /^(a.*?c)/'
abc
# YES! non-greedy match现在看看这个,当锚定到最后的时候:
$ echo abcabcabc | perl -ne 'print $1 if /(a.*c)$/'
abcabcabc
# OK, greedy match
$ echo abcabcabc | perl -ne 'print $1 if /(a.*?c)$/'
abcabcabc
# what, non-greedy become greedy?为什么会这样呢?为什么它不像以前那样打印abc?
(在我的Go代码中发现了这个问题,但为了简单起见,在Perl中作了说明)。
发布于 2016-12-06 02:53:52
$ echo a perl -ne‘打印$1如果/(a*?c)$/’abcabcabc #什么,非贪婪变成贪婪?
非贪婪意味着它将匹配当前位置上可能最少的字符,从而使整个模式匹配。
在将a匹配到0位置之后,bcabcab是在1位置可以匹配的最少的.*?,但仍然满足模式的其余部分。
详细的"abcabcabc" = /a.*?c$/:
a匹配1个字符(a)。.*?匹配0个字符(空字符串)。c无法匹配。回溯!
1. At pos 1, `.*?` matches 1 char (`b`).
1. At pos 2, `c` matches 1 char (`c`).
1. At pos 3, `$` fails to match. Backtrack!
1. At pos 1, `.*?` matches 2 chars (`bc`).
1. At pos 1, `c` fails to match. Backtrack!
1. ...
2. At pos 1, `.*?` matches 7 chars (`bcabcab`).
1. At pos 8, `c` matches 1 char (`c`).
1. At pos 9, `$` matches 0 chars (empty string). Match successful!
详细的"abcabcabc" = /a.*c$/ (用于对比):
a匹配1个字符(a)。.*匹配8个字符(abcabcabc)。c无法匹配。回溯!
1. At pos 1, `.*` matches 7 chars (`abcabcab`).
1. At pos 8, `c` matches 1 char (`c`).
1. At pos 9, `$` matches 0 chars (empty string). Match successful!
提示:避免使用两种非贪婪修饰符的模式。除非您使用它们作为优化,否则它们很有可能匹配您不希望它们匹配的东西。这在这里是相关的,因为模式隐式地从\G(?s:.*?)\K开始(除非由领先的^、\A或\G取消)。
您想要的是以下内容之一:
/a[^a]*c$/
/a[^c]*c$/
/a[^ac]*c$/您还可以使用以下内容之一:
/a(?:(?!a).)c$/s
/a(?:(?!c).)c$/s
/a(?:(?!a|c).)c$/s在这种情况下使用后三个字符将是低效和不可读的,但它们的边界将超过一个字符。
https://stackoverflow.com/questions/40986527
复制相似问题