我一直在代码高尔夫交易所处理这个问题,这就是为什么我的代码看起来很有趣.
这是一个程序,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.
}
Run Code Online (Sandbox Code Playgroud)
这是输出:
111111111111111111111111111111111
#$%&04689@ABDOPQRabdegopq
Run Code Online (Sandbox Code Playgroud)
这可以像我期望的那样工作.但是,当我^取出第二个正则表达式时,正则表达式不再匹配和延长字符串.
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!
}
Run Code Online (Sandbox Code Playgroud)
为什么会这样?s//1/在第一个循环中工作,那么为什么在第二个循环中更改它会破坏一切?
另外还有一点困惑,如果你把if块放在大括号中,那么正则表达式会再次匹配:
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.
}
Run Code Online (Sandbox Code Playgroud)
我想将原始代码编辑回问题以供参考:
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
}
Run Code Online (Sandbox Code Playgroud)
当我们^从该行中删除时,输出将从:
test1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1testtest1test111111111111111111111111111111111
#$%&04689@ABDOPQRabdegopq
Run Code Online (Sandbox Code Playgroud)
至
挂着没有输出
所以在这种情况下,第二个循环中的换行会改变它看起来的第一个行为.
扩展弗拉基米尔的答案
print "regex have dynamic scope\n";
$_ = 1;
{
m/1/;
s//2/;
print "$_ one becomes two, s//2/ is really s/1/2/\n";
}
$_=1;
{
m/1/;
{
s//2/;
}
print "$_ one still becomes two, s//2/ is really s/1/2/\n";
}
$_=1;
{
{
m/1/;
}
s//2/;
print "$_ one becomes twentyone, s//2/; is really s/(?:)//2;\n";
}
__END__
regex have dynamic scope
2 one becomes two, s//2/ is really s/1/2/
2 one still becomes two, s//2/ is really s/1/2/
21 one becomes twentyone, s//2/; is really s/(?:)//2;
Run Code Online (Sandbox Code Playgroud)
由于正则表达式具有动态范围,因此使用空模式 //实际上意味着使用同一动态范围中的先前模式,所以不要这样做:)
如果添加,use re 'debug';您可以看到正则表达式引擎使用先前的模式(重点关注Matching REx语句,NOTHING(2)没有前一个为空,EXACT <1>(3)是先前的模式)
regex have dynamic scope
Guessing start of match in sv for REx "1" against "1"
Found anchored substr "1" at offset 0...
Guessed: match at offset 0
Guessing start of match in sv for REx "1" against "1"
Found anchored substr "1" at offset 0...
Guessed: match at offset 0
Matching REx "1" against "1"
0 <> <1> | 1:EXACT <1>(3)
1 <1> <> | 3:END(0)
Match successful!
2 one becomes two, s//2/ is really s/1/2/
Guessing start of match in sv for REx "1" against "1"
Found anchored substr "1" at offset 0...
Guessed: match at offset 0
Guessing start of match in sv for REx "1" against "1"
Found anchored substr "1" at offset 0...
Guessed: match at offset 0
Matching REx "1" against "1"
0 <> <1> | 1:EXACT <1>(3)
1 <1> <> | 3:END(0)
Match successful!
2 one still becomes two, s//2/ is really s/1/2/
Guessing start of match in sv for REx "1" against "1"
Found anchored substr "1" at offset 0...
Guessed: match at offset 0
Matching REx "" against "1"
0 <> <1> | 1:NOTHING(2)
0 <> <1> | 2:END(0)
Match successful!
21 one becomes twentyone, s//2/; is really s/(?:)//2;
Run Code Online (Sandbox Code Playgroud)
更新:因为你有一个无限循环;最后一个模式总是有 1,所以替换本质上是 s/1/1/;这意味着你的字符串不会增长,它总是 33 个字符......请参阅更新:)
$_="";
until( y/1/1/ > 32){
print "test1";
s//1/;
print "test";
}
print "$_\n";
my $max = 126;
my $count = 0;
my $reps = 0;
until( y/1/1/ > 125+1 ) {
if( chr(y/1/1/) !~ /[!"'()*+,-.\/12357:;<=>?CEFGHIJKLMNSTUVWXYZ[\\\]^_`cfhijklmnrstuvwxyz{|}~]/ ) {
print chr y/1/1/;
}
$reps =
#~ s/^/1/; # win
s//1/; # fail
$count++;
last if $count > $max;
}
print "m $max c $count r $reps l @{[ length $_ ]}\n";
__END__
win #$%&04689@ABDOPQRabdegopqm 126 c 94 r 1 l 127
fail m 126 c 127 r 1 l 33
Run Code Online (Sandbox Code Playgroud)
除非你混淆了append is$_ .= 1;和prepend is$_ = 1 . $_;
| 归档时间: |
|
| 查看次数: |
210 次 |
| 最近记录: |