经过对此事的大量研究后,我来请求你的帮助:
我正在尝试限制Perl正则表达式对大文本执行的替换的重复。 我在谷歌搜索过,发现格式为{2,3}(最小值,最大值),但这似乎与我正在使用的语法不同。
$replaced=~s/$var/$var2/g; # replaces all ocurrences
$replaced=~s/$var/$var2/; # replaces only first one
我的非最佳解决方案:
for($i=0; $i<8; $i++){
$replaced=~s/$var/$var2/;
}
我尝试过:
$replaced=~s/$var/$var2/{8};
$replaced=~s/$var/$var2{8}/;
任何帮助将不胜感激!
编辑: 好吧,所以几乎必须有一个循环参与呵呵..是不是很奇怪没有内置参数来限制它?
答案 0 :(得分:7)
\G
的答案可能是做你想做的最实用的方法,但只是为了好玩或启发或其他什么,这是另一种方式(需要perl 5.10或更高版本),使用代码断言和{ {3}} (*COMMIT)
和(*FAIL)
:
my $str = "Bananas in pajamas are coming down the stairs";
my $limit = 3;
my $count;
$str =~ s/(*COMMIT)(?(?{ $count++ >= 3 })(*FAIL))a/A/g;
say $str;
在$str
中留下了“睡衣中的BAnAnAs下楼” - 只有前三个“a”受到影响,并且在第三个之后它停止扫描字符串以获得更多匹配。
答案 1 :(得分:4)
我不熟悉Perl,但我相信你想使用“\G
断言”(more info here),它将继续在上一场比赛离开的地方搜索新的比赛关:
for($i=0; $i<8; $i++){
$replaced=~s/\G$var/$var2/;
}
我不确定它是否实际上更有效率,但它似乎就是它的目的......
答案 2 :(得分:1)
答案:http://codenode.com/2010/06/24/single-pass-replace-with-perl-regex-g-anchor/
摘录并修改了计数器:
my $cnt = 0;
if ( $query =~ m/\bORDER BY /gi ) {
while ($query =~ s/\G(.+?)\s+ASC/$1/gmsi && pos $query) {
$cnt++; last if $cnt >= 8;
}
}