从
extracting the n’th regex match的早期问题开始,我现在需要替换匹配,如果找到的话.
我认为我可以定义提取子例程并在/ e修饰符的替换中调用它.我显然是错的(诚然,我有一个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','to process this' 'line'
当然,这种技术存在许多其他问题:
>如果在不同的位置有相同的比赛怎么办?
>如果找不到比赛怎么办?
鉴于这种情况,我想知道这可以通过哪些方式实施.
解决方法
或者你可以这样做
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变量,可以抛光,但你明白了.
更新:更紧凑的版本:
use strict; my $string = "'How can I','to process this' 'line'"; #replace the $index n'th match (1-based counting) from $string by $replacement sub replace_quoted { my ($string,$replacement) = @_; my $cont = 0; # initialize match counter $string =~ s/'(.*?)'/$cont++ == $index ? $replacement : $1/eg; return $string; } my $result = replace_quoted ( $string,"PERL"); print "RESULT: $result\n";