我一直在研究 this problem在代码高尔夫交换中,这就是为什么我的代码看起来如此有趣。
这是一个使用 use strict
和 use warnings
重现问题的程序:
use strict;
use warnings;
$_ = "";
for my $i (1..33){
s//1/; # Just prepends 1 to the string $_
}
print "$_\n";
for my $i (34..127) {
if( chr(y/1/1/) !~ /[!"'()*+,-.\/12357:;<=>?CEFGHIJKLMNSTUVWXYZ[\\\]^_`cfhijklmnrstuvwxyz{|}~]/ ) {
print chr y/1/1/;
}
s/^/1/; # Prepends 1 to the start of the string.
}
这是输出:
111111111111111111111111111111111
#$%&04689@ABDOPQRabdegopq
这正如我所期望的那样。但是,当我从第二个正则表达式中取出 ^
时,正则表达式不再匹配并延长字符串。
use strict;
use warnings;
$_ = "";
for my $i (1..33){
s//1/;
}
print "$_\n";
for my $i (34..127) {
if( chr(y/1/1/) !~ /[!"'()*+,-.\/12357:;<=>?CEFGHIJKLMNSTUVWXYZ[\\\]^_`cfhijklmnrstuvwxyz{|}~]/ ) {
print chr y/1/1/;
}
s//1/; # No Longer matches!
}
为什么会发生这种情况? s//1/
在第一个循环中有效,那么为什么在第二个循环中更改它会破坏一切呢?
还有一个令人困惑的地方,如果将 if block 放在大括号中,则正则表达式会再次匹配:
for my $i (34..127) {
{
if( chr(y/1/1/) !~ /[!"'()*+,-.\/12357:;<=>?CEFGHIJKLMNSTUVWXYZ[\\\]^_`cfhijklmnrstuvwxyz{|}~]/ ) {
print chr y/1/1/;
}
}
s//1/; # This prepends 1 to the string $_ again.
}
编辑:
我想将原始代码编辑回到问题中以供引用:
use strict;
use warnings;
$_="";
until( y/1/1/ > 32){
print "test1";
s//1/;
print "test";
}
print "$_\n";
until( y/1/1/ > 125+1 ) {
if( chr(y/1/1/) !~ /[!"'()*+,-.\/12357:;<=>?CEFGHIJKLMNSTUVWXYZ[\\\]^_`cfhijklmnrstuvwxyz{|}~]/ ) {
print chr y/1/1/;
}
s/^/1/; # this is the line we remove ^ from
}
当我们从该行中删除 ^
时,输出将更改为:
test1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1test111111111111111111111111111111111
#$%&04689@ABDOPQRabdegopq
至
hanging with no output
因此,在这种情况下,第二个循环中的行更改似乎改变了第一个循环的行为。
最佳答案
s//1/;
不检查任何字符串或空字符串。它会检查之前最后一次成功的正则表达式文本。因此,第一个循环使用默认正则表达式,第二个循环使用上面 if
中最后一次成功的检查。
引用:
If the PATTERN evaluates to the empty string, the last successfully matched regular expression is used instead. In this case, only the g and c flags on the empty pattern are honored
关于regex - 从 `^` 中删除 `s/^/1/;` 会导致我的代码失败。为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25026656/