在codegold中,我找到了这个答案:https://codegolf.stackexchange.com/a/34345/29143,这是perl one liner:
perl -e '(q x x x 10) =~ /(?{ print "hello\n" })(?!)/;'
-MO = Deparse得到后:
' ' =~ /(?{ print "hello\n" })(?!)/;
^^^^^^^^^^^^
10 spaces
说明的解释比(?!)
从不匹配,所以正则表达式尝试匹配每个字符。好的,但为什么它打印11次你好而不是10次?
答案 0 :(得分:2)
这是因为当你有一串n个字符时,在测试模式的字符串中有n + 1个位置。
"abc"
的例子:
a b c
^ ^ ^ ^
| | | |
| | | +--- end of the string
| | +----- position of c
| +------- position of b
+--------- position of a
字符串结尾的位置可能有点违反直觉,但这个位置存在。为了说明这一事实,请考虑使用示例字符串成功的模式/c$/
。 (考虑结束锚点测试时字符串中的位置)。或者在最后一个位置成功的另一个/(?<=c)/
。
答案 1 :(得分:2)
看看以下内容:
$x = "abc"; $x =~ s/.{0}/x/; print("$x\n"); # xabc
$x = "abc"; $x =~ s/.{1}/x/; print("$x\n"); # xbc
$x = "abc"; $x =~ s/.{2}/x/; print("$x\n"); # xc
$x = "abc"; $x =~ s/.{3}/x/; print("$x\n"); # x
没什么好奇怪的。您可以匹配三个字符中0到3之间的任意位置,并将x
放在您离开的位置。这是三个角色的四个位置。
另请考虑'abc' =~ /^abc\z/
。
0
开始,^
匹配零字符。0
开始,a
匹配一个字符。1
开始,b
匹配一个字符。2
开始,c
匹配一个字符。3
开始,\z
匹配零字符。同样,这是三个字符串所需的总共四个位置。
只有零宽度断言可以在最后一个位置匹配,但有很多断言(^
,\z
,\b
,(?=...)
,{{1} },(?!...)
,(?<=...)
等。)
如果有帮助,您可以将这些位置视为角色的边缘。
(?:...)?
答案 2 :(得分:2)
正则表达式基于关闭位置开始匹配,其可以包括在每个字符之前,也包括在最后一个字符之后。
以下零宽度正则表达式将在字符串的5个字符中的每个字符之前匹配,但也在最后一个字符之后匹配,从而说明为什么您有11个打印而不是10个。
use strict;
use warnings;
my $string = 'ABCDE';
# Zero width Regular expression
$string =~ s//x/g;
print $string;
输出:
xAxBxCxDxEx
^ ^ ^ ^ ^ ^
1 2 3 4 5 6