如何使用正则表达式限制perl上找到的匹配?

时间:2011-11-11 17:44:31

标签: regex perl

经过对此事的大量研究后,我来请求你的帮助:

我正在尝试限制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}/;

任何帮助将不胜感激!

编辑: 好吧,所以几乎必须有一个循环参与呵呵..是不是很奇怪没有内置参数来限制它?

3 个答案:

答案 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;
   }
}