如何在字符串中找到重叠的正则表达式?

时间:2015-11-18 11:47:09

标签: arrays regex string perl

我有这个字符串:

my $line = "MZEFSRGGRMEAZFE*MQZEFFMAEZF*"

我想找到以M开头并以*结尾的每个子字符串,其中不包含*。这意味着上面的字符串会给我最后一个数组中的4个元素。

@ORF= (MZEFSRGGRMEAZFE*,MEAZFE*, MQZEFFMAEZF*,MAEZF*)

一个简单的正则表达式不会发生,因为它找不到重叠的子串。有一种简单的方法可以做到这一点吗?

2 个答案:

答案 0 :(得分:5)

正则表达式匹配在匹配时消耗模式 - 这是设计的。

您可以使用超前表达式来避免这种情况发生PerlMonks: Using Look-ahead and Look-behind

所以这样的事情会起作用:

#!/usr/bin/env perl
use strict;
use warnings;

use Data::Dumper;

my $line = "MZEFSRGGRMEAZFE*MQZEFFMAEZF*";
my @matches = $line  =~ m/(?=(M[^*]+))/g;
print Dumper \@matches;

这给了你:

$VAR1 = [
          'MZEFSRGGRMEAZFE',
          'MEAZFE',
          'MQZEFFMAEZF',
          'MAEZF'
        ];

答案 1 :(得分:2)

您也可以使用递归方法而不是高级功能正则表达式来执行此操作。下面的程序会进行每次匹配并重新匹配匹配,但省略了起始M,因此它不会再次与整个匹配。

use strict;
use warnings;
use Data::Printer;

my $line = "MZEFSRGGRMEAZFE*MQZEFFMAEZF*";
my @matches;

sub parse {
    my ( $string ) = @_;

    while ($string =~ m/(M[^*]+\*)/g ) {
        push @matches, $1;
        parse(substr $1, 1);
    }
}

parse($line);
p @matches;

这是输出:

[
    [0] "MZEFSRGGRMEAZFE*",
    [1] "MEAZFE*",
    [2] "MQZEFFMAEZF*",
    [3] "MAEZF*"
]