Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex Perl正则表达式替换计数_Regex_Perl - Fatal编程技术网

Regex Perl正则表达式替换计数

Regex Perl正则表达式替换计数,regex,perl,Regex,Perl,是否可以指定要替换的最大匹配数。例如,如果在“Hello World”中匹配“l”,是否可以替换前2个“l”字符,但不能替换没有循环的第三个字符?简短回答:否。您需要在某种循环中执行替换。这里有一种方法。这需要在使用(?(条件)真子表达式|假子表达式)构造内部的(?{code})块的情况下更新外部计数器。请参阅以获取解释 use Modern::Perl; use re qw/eval/; # Considered experimental. my $string = 'Hello world

是否可以指定要替换的最大匹配数。例如,如果在“Hello World”中匹配“l”,是否可以替换前2个“l”字符,但不能替换没有循环的第三个字符?

简短回答:否。您需要在某种循环中执行替换。

这里有一种方法。这需要在使用
(?(条件)真子表达式|假子表达式)
构造内部的
(?{code})
块的情况下更新外部计数器。请参阅以获取解释

use Modern::Perl;
use re qw/eval/; # Considered experimental.

my $string = 'Hello world!';

my $count = 2;

my $re =    qr/
                (l)
                (?(?{$count--})|(*FAIL))
            /x;

say "Looking for $count instances of 'l' in $string.";
my ( @found ) = $string =~ m/$re/g;
say "Found ", scalar @found, " instances of 'l': @found";
输出为:

Looking for 2 instances of 'l' in Hello world!
Found 2 instances of 'l': l l
Found l at 3
Found l at 4
这里是对同一个regexp的另一个测试,但这次我们跟踪匹配的位置,只是为了证明它与前两次匹配

use Modern::Perl;
use strict;
use warnings;
use re qw/eval/; # Considered experimental.

my $string = 'Hello world!';

my $count = 2;
my $position = 0;

my $re =    qr/
                (l)(?{$position=pos})
                (?(?{$count--})|(*FAIL))
            /x;

while( $string =~ m/$re/g ) {
    say "Found $1 at ", $position;
}
这次的输出是:

Looking for 2 instances of 'l' in Hello world!
Found 2 instances of 'l': l l
Found l at 3
Found l at 4
我不认为我会推荐这些。如果我考虑只将匹配约束到字符串的一部分,那么我将匹配字符串的
substr()
。但是,如果你喜欢生活在边缘,那就去享受这段经历吧

这是一个替代品:

use Modern::Perl;
use strict;
use warnings;
use re qw/eval/; # Considered experimental.

my $string = 'Hello world!';
say "Before substitution $string";
my $count = 2;
my $re =    qr/
                (l)
                (?(?{$count--})|(*FAIL))
            /x;

 $string =~ s/$re/L/g;

 say "After substitution  $string";
以及输出:

Before substitution Hello world!
After substitution  HeLLo world!
我不明白循环有什么不好

实际上,这里有一个方法:

$str="Hello world!"; 
$str =~ s/l/$i++ >= 2 ? "l": "r"/eg; 
print $str;

这是一个循环,因为当你这样做的时候,s///g是以一种循环的方式工作的。但这不是一个传统的循环。

您可以使用python
re.sub(repl,string[,count=0])
,但这显然不是您所追求的。这可能是升级到python所需要的动机。@Quick:up?当然,你的意思是向下。我喜欢编写Perl,但我并不特别喜欢阅读它。注意:我真的很想通过YAPE::Regex::Explain来运行它,以显示发生了什么,但不幸的是,它没有生成对正在发生的事情的准确描述。另一条评论,如果有人还在读:任何包含嵌入在regexp本身中的计数器的方法都可能对RE引擎的回溯非常敏感。只是一个想法。
@re=qw(l);s/(l)/shift@re | | | 1美元/加仑这很可爱,但它的实用性在某种程度上仅限于最琐碎的正则表达式模式。你在答案中发布的版本更有用。后一种方式如何“循环”?它只遍历字符串一次,对吗?@Tim Nordenfur:每次找到匹配项时,它都会求值,但是的,只遍历字符串一次。你可以做
while(/match/g)
来创建一个循环。每个方法都是一个循环。有显式循环(看起来像'while'或'foreach'的循环)和隐式循环(没有名称但发生在幕后的循环)。没有隐式循环就没有遍历(甚至一次)。它只是隐藏在RE引擎的/g子句中。