如何在 Perl 正则表达式中替换第 n 次匹配? [英] How can I substitute the nth occurrence of a match in a Perl regex?
问题描述
跟进关于 提取第 n 个正则表达式匹配,如果找到,我现在需要替换匹配.
Following up from an earlier question on extracting the n'th regex match, I now need to substitute the match, if found.
我认为我可以定义提取子例程并使用 /e
修饰符在替换中调用它.我显然错了(诚然,我有一个 XY 问题).
I thought that I could define the extraction subroutine and call it in the substitution with the /e
modifier. I was obviously wrong (admittedly, I had an XY problem).
use strict;
use warnings;
sub extract_quoted { # à la codaddict
my ($string, $index) = @_;
while($string =~ /'(.*?)'/g) {
$index--;
return $1 if(! $index);
}
return;
}
my $string = "'How can I','use' 'PERL','to process this' 'line'";
extract_quoted ( $string, 3 );
$string =~ s/&extract_quoted($string,2)/'Perl'/e;
print $string; # Prints 'How can I','use' 'PERL','to process this' 'line'
当然,这种技术还有许多其他问题:
There are, of course, many other issues with this technique:
- 如果在不同位置有相同的匹配怎么办?
- 如果找不到匹配项怎么办?
鉴于这种情况,我想知道可以通过哪些方式实现.
In light of this situation, I'm wondering in what ways this could be implemented.
推荐答案
或者你可以这样做
use strict;
use warnings;
my $string = "'How can I','use' .... 'perl','to process this' 'line'";
my $cont =0;
sub replacen { # auxiliar function: replaces string if incremented counter equals $index
my ($index,$original,$replacement) = @_;
$cont++;
return $cont == $index ? $replacement: $original;
}
#replace the $index n'th match (1-based counting) from $string by $rep
sub replace_quoted {
my ($string, $index,$replacement) = @_;
$cont = 0; # initialize match counter
$string =~ s/'(.*?)'/replacen($index,$1,$replacement)/eg;
return $string;
}
my $result = replace_quoted ( $string, 3 ,"PERL");
print "RESULT: $result\n";
全局" $cont 变量有点丑,可以改进,但你懂的.
A little ugly the "global" $cont variable, that could be polished, but you get the idea.
更新:更紧凑的版本:
use strict;
my $string = "'How can I','use' .... 'perl','to process this' 'line'";
#replace the $index n'th match (1-based counting) from $string by $replacement
sub replace_quoted {
my ($string, $index,$replacement) = @_;
my $cont = 0; # initialize match counter
$string =~ s/'(.*?)'/$cont++ == $index ? $replacement : $1/eg;
return $string;
}
my $result = replace_quoted ( $string, 3 ,"PERL");
print "RESULT: $result\n";
这篇关于如何在 Perl 正则表达式中替换第 n 次匹配?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!