如何替换 Perl 正则表达式中第 n 次出现的匹配项?
跟进之前的问题 提取第 n 个正则表达式匹配,我现在需要替换该匹配(如果找到)。
我认为我可以定义提取子例程并在使用 /e
修饰符的替换中调用它。我显然错了(诚然,我有一个 XY 问题)。
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'
当然,这种技术还存在许多其他问题:
- 如果不同位置有相同的匹配怎么办?
- 如果没有找到匹配怎么办?
鉴于这种情况,我想知道可以通过哪些方式来实现。
Following up from an earlier question on extracting the n'th regex match, I now need to substitute the match, if found.
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:
- What if there are identical matches at different positions?
- What if the match isn't found?
In light of this situation, I'm wondering in what ways this could be implemented.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
请参阅 perldoc perlvar:
输出:
当然,您需要决定如果传递了无效的
$index
或未找到所需的匹配项。我只是返回上面代码中的原始字符串。See perldoc perlvar:
Output:
Of course, you need to decide what happens if an invalid
$index
is passed or if the required match is not found. I just return the original string in the code above.重新设计 回答之前的问题,匹配n-1次,然后替换下一个。记忆模式使可怜的 Perl 不必一遍又一遍地重新编译相同的模式。
例如
输出
Reworking an answer to an earlier question, match n-1 times and then replace the next. Memoizing patterns spares poor Perl having to recompile the same patterns over and over.
For example
outputs
编辑: leonbloy 首先提出了这个解决方案。如果您想投票,请先投票 leonbloy。
受到 leonbloy(之前)的回答的启发:
EDIT: leonbloy came up with this solution first. If your tempted to upvote it, upvote leonbloy's first.
Somewhat inspired by leonbloy's (earlier) answer:
或者你可以做一些像
“全局”$cont 变量有点难看的事情,可以改进,但你明白了。
更新:更紧凑的版本:
Or you can do something as this
A little ugly the "global" $cont variable, that could be polished, but you get the idea.
Update: a more compact version:
如果正则表达式并不比您所拥有的复杂太多,您可以在
split
之后进行编辑和join
:If the regex isn't too much more complicated than what you have, you could follow a
split
with an edit and ajoin
: