Perl查找替换(带编号替换)进入死循环
Perl find-and-replace (with numbered replacement) enters infinite loop
今天早些时候我 post 提出了一个类似的问题,其解决方案导致了一个新问题,-,-
嗯,故事是我希望 Perl 从文本中捕获评论,将它们存储在数组中,并用新的编号评论替换它们,例如,对于原始 $txt:
//first comment
this is a statement //second comment
//third comment
more statements //fourth comment
我想将 4 条评论推入一个数组,并获取新的 $txt,例如:
//foo_0
this is a statement //foo_1
//foo_2
more statements //foo_3
我尝试了以下 Perl:
$i=0;
$j=0;
#while ($txt =~ s/(\/\/.*?\n)/\/\/foo_$i\n/gs) {
#while ($txt =~ s/(\/\/.*?\n)/\/\/foo_$i\n/s) {
#foreach ($txt =~ s/(\/\/.*?\n)/\/\/foo_$i\n/gs) {
foreach ($txt =~ s/(\/\/.*?\n)/\/\/foo_$i\n/s) {
if(defined ) {
push (@comments, );
print " $i=$i\n";
$i++
}
print " $j=$j\n";
$j++;
}
print "after search & replace, we have $txt:\n";
print $txt;
foreach (0..$#comments) {
print "\@comments[$_]= @comments[$_]";
}
在里面,我尝试了四种口味的"while/foreach (... s///gs)",但其中none确实达到了我想要的效果。
"foreach" 语句仅对文本起作用一次;更糟糕的是,"while" 语句将进入无限循环,似乎新的“//foo_xx”东西被放回字符串中以进行进一步的搜索操作,从而使其成为无限循环。奇怪的是,这么一个看似简单的查找和替换机制会陷入死循环,还是有什么明显的技巧我不知道?
顺便说一句,我已经完成了 post by highsciguy 。对他来说,"simply replacing while with foreach in the above code will do";但对我来说,foreach 不起作用,我不知道为什么。
有没有人能帮我解决这个问题?谢谢~
我会以不同的方式处理它 - 一个 while 循环逐行读取文件句柄,'grab' 从中读取所有注释行。
像这样:
#!/usr/bin/perl
use warnings;
use strict;
my @comments;
#iterate stdin or filename specified on command line
while ( <> ) {
#replace anything starting with // with foo_nn
#where nn is current number of comments.
s,//(.*),"//foo_".@comments,e && push (@comments, );
# is the contents of that bracket - the string we replaced
#stuff it into commments;
#print the current line (altered by the above)
print;
}
#print the comments.
print "Comments:\n", join "\n", @comments;
不解决重复问题,如果您在引号或其他内容中包含 //
,则会中断,但确实适用于您的示例。 while
基于文件句柄逐行迭代。如果您已经有了带有文本 blob 的标量,那么您可以使用 foreach ( split ( "\n", $text ) ) {
完成同样的事情
输出:
//foo_0
this is a statement //foo_1
//foo_2
more statements //foo_3
Comments:
first comment
second comment
third comment
fourth comment
遍历文本的每一行,如果替换成功,则存储注释:
#!/usr/bin/perl
use strict;
use warnings;
my $txt = <<END; # define text
//first comment
this is a statement //second comment
//third comment
more statements //fourth comment
END
my @comments = ();
my $i = 0;
foreach (split qq(\n), $txt) { # iterate over input lines
if (s&(//.*)&//foo_$i&) { # do we match?
push @comments, ; # then push comment
$i++; # and increase counter
}
print; # print modified row
print qq(\n); # print newline
}
print qq(\nComments:\n);
foreach (@comments) {
print; # print the comment
print qq(\n); # print newline
}
今天早些时候我 post 提出了一个类似的问题,其解决方案导致了一个新问题,-,-
嗯,故事是我希望 Perl 从文本中捕获评论,将它们存储在数组中,并用新的编号评论替换它们,例如,对于原始 $txt:
//first comment
this is a statement //second comment
//third comment
more statements //fourth comment
我想将 4 条评论推入一个数组,并获取新的 $txt,例如:
//foo_0
this is a statement //foo_1
//foo_2
more statements //foo_3
我尝试了以下 Perl:
$i=0;
$j=0;
#while ($txt =~ s/(\/\/.*?\n)/\/\/foo_$i\n/gs) {
#while ($txt =~ s/(\/\/.*?\n)/\/\/foo_$i\n/s) {
#foreach ($txt =~ s/(\/\/.*?\n)/\/\/foo_$i\n/gs) {
foreach ($txt =~ s/(\/\/.*?\n)/\/\/foo_$i\n/s) {
if(defined ) {
push (@comments, );
print " $i=$i\n";
$i++
}
print " $j=$j\n";
$j++;
}
print "after search & replace, we have $txt:\n";
print $txt;
foreach (0..$#comments) {
print "\@comments[$_]= @comments[$_]";
}
在里面,我尝试了四种口味的"while/foreach (... s///gs)",但其中none确实达到了我想要的效果。
"foreach" 语句仅对文本起作用一次;更糟糕的是,"while" 语句将进入无限循环,似乎新的“//foo_xx”东西被放回字符串中以进行进一步的搜索操作,从而使其成为无限循环。奇怪的是,这么一个看似简单的查找和替换机制会陷入死循环,还是有什么明显的技巧我不知道?
顺便说一句,我已经完成了 post by highsciguy 。对他来说,"simply replacing while with foreach in the above code will do";但对我来说,foreach 不起作用,我不知道为什么。
有没有人能帮我解决这个问题?谢谢~
我会以不同的方式处理它 - 一个 while 循环逐行读取文件句柄,'grab' 从中读取所有注释行。
像这样:
#!/usr/bin/perl
use warnings;
use strict;
my @comments;
#iterate stdin or filename specified on command line
while ( <> ) {
#replace anything starting with // with foo_nn
#where nn is current number of comments.
s,//(.*),"//foo_".@comments,e && push (@comments, );
# is the contents of that bracket - the string we replaced
#stuff it into commments;
#print the current line (altered by the above)
print;
}
#print the comments.
print "Comments:\n", join "\n", @comments;
不解决重复问题,如果您在引号或其他内容中包含 //
,则会中断,但确实适用于您的示例。 while
基于文件句柄逐行迭代。如果您已经有了带有文本 blob 的标量,那么您可以使用 foreach ( split ( "\n", $text ) ) {
输出:
//foo_0
this is a statement //foo_1
//foo_2
more statements //foo_3
Comments:
first comment
second comment
third comment
fourth comment
遍历文本的每一行,如果替换成功,则存储注释:
#!/usr/bin/perl
use strict;
use warnings;
my $txt = <<END; # define text
//first comment
this is a statement //second comment
//third comment
more statements //fourth comment
END
my @comments = ();
my $i = 0;
foreach (split qq(\n), $txt) { # iterate over input lines
if (s&(//.*)&//foo_$i&) { # do we match?
push @comments, ; # then push comment
$i++; # and increase counter
}
print; # print modified row
print qq(\n); # print newline
}
print qq(\nComments:\n);
foreach (@comments) {
print; # print the comment
print qq(\n); # print newline
}