Perl Regex多重匹配

Joh*_*ann 5 regex perl backreference

我正在寻找一个表现如下的正则表达式:

输入:"你好世界".

输出:he,el,ll,lo,wo或rl,ld

我的想法是有道理的

    while($string =~ m/(([a-zA-Z])([a-zA-Z]))/g) {
        print "$1-$2 ";
    }
Run Code Online (Sandbox Code Playgroud)

但这确实有点不同.

tch*_*ist 10

这很棘手.您必须捕获它,保存它,然后强制回溯.

你可以这样做:

use v5.10;   # first release with backtracking control verbs

my $string = "hello, world!";
my @saved;

my $pat = qr{
    ( \pL {2} )
    (?{ push @saved, $^N })
    (*FAIL)
}x;

@saved = ();
$string =~ $pat;
my $count = @saved;
printf "Found %d matches: %s.\n", $count, join(", " => @saved);
Run Code Online (Sandbox Code Playgroud)

产生这个:

Found 8 matches: he, el, ll, lo, wo, or, rl, ld.
Run Code Online (Sandbox Code Playgroud)

如果您没有v5.10,或者您头疼,可以使用:

my $string = "hello, world!";
my @pairs = $string =~ m{
  # we can only match at positions where the
  # following sneak-ahead assertion is true:
    (?=                 # zero-width look ahead
        (               # begin stealth capture
            \pL {2}     #       save off two letters
        )               # end stealth capture
    )
  # succeed after matching nothing, force reset
}xg;

my $count = @pairs;
printf "Found %d matches: %s.\n", $count, join(", " => @pairs);
Run Code Online (Sandbox Code Playgroud)

这产生与以前相同的输出.

但是你可能仍然会头疼.


ike*_*ami 5

不需要"强制回溯"!

push @pairs, "$1$2" while /([a-zA-Z])(?=([a-zA-Z]))/g;
Run Code Online (Sandbox Code Playgroud)

虽然您可能希望匹配任何字母而不是您指定的有限集.

push @pairs, "$1$2" while /(\pL)(?=(\pL))/g;
Run Code Online (Sandbox Code Playgroud)