【问题标题】:How do I find overlapping regex in a string?如何在字符串中找到重叠的正则表达式?
【发布时间】:2016-02-20 03:23:08
【问题描述】:

我有这个字符串:

my $line = "MZEFSRGGRMEAZFE*MQZEFFMAEZF*"

我想找到以M 开头并以* 结尾的每个子字符串,其中没有*。这意味着上面的字符串将在我的最终数组中给我 4 个元素。

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

一个简单的正则表达式是行不通的,因为它找不到重叠的子字符串。有没有简单的方法可以做到这一点?

【问题讨论】:

  • 你错过了MZEFSRGGRMEAZFE*MQZEFFMAEZF*。你有什么尝试吗?
  • @AvinashRaj 不,完整的字符串包含* instide,所以这不是结果的一部分。
  • @AvinashRaj simbabque 是正确的,它不会成为最终数组的一部分,因为其中有一个“*”。我使用的代码没有找到重叠的子字符串,这是我的问题。
  • 以后,请添加您已经编写并且遇到问题的代码。这让我们更容易提供帮助。

标签: arrays regex string perl


【解决方案1】:

正则表达式匹配在匹配时使用模式 - 这是设计使然。

您可以使用前瞻表达式来避免这种情况发生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'
        ];

【讨论】:

    【解决方案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*"
    ]
    

    【讨论】:

      猜你喜欢
      • 2017-10-27
      • 2017-03-15
      • 2011-01-27
      • 2014-01-16
      • 1970-01-01
      • 2016-02-16
      • 1970-01-01
      相关资源
      最近更新 更多