Perl正则表达式匹配模式的多个实例并替换

时间:2011-03-18 13:32:33

标签: regex perl

我有一个看起来像这样的字符串:

abc[1,2,3].something.here,foo[10,6,34].somethingelse.here,def[1,2].another

我想将此字符串拆分为包含以下内容的数组:

abc[1,2,3].something.here
foo[10,6,34].somethingelse.here
def[1,2].another

但是对评论的拆分不会有效,所以我的下一个想法是首先用方括号替换位于方括号之间的逗号,这样我就可以在逗号上拆分,然后在事后替换。

我尝试过几种方法但收效甚微..有什么建议吗?

5 个答案:

答案 0 :(得分:4)

您可以在模式中使用先行断言:

my $s = "abc[1,2,3].something.here,foo[10,6,34].somethingelse.here,def[1,2].another";
my @a = split /,(?=\w+\[)/, $s;

答案 1 :(得分:1)

当事情变得复杂时,我喜欢解析器方法。

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

my $statement  =  "abc[1,2,3].something.here,foo[10,6,34].somethingelse.here,def[1,2].another";

my $index      = qr/\[(?:\d+)(?:,\d+)*\]/;
my $variable   = qr/\w+$index?/;
my $expression = qr/$variable(?:\.$variable)*/;

my @expressions = ($statement =~ /($expression)/g);

print "$_\n" for @expressions;

答案 2 :(得分:0)

遍历字符串中的字符(伪代码):

found_closing_bracket = 0;
buffer = ''
array = []

foreach c in str:

   if c == ']'
      found_closing_bracket = 1

   if c == ',' && found_closing_bracket == 1
     push(array, buffer)
     buffer = ''
     found_closing_bracket = 0

   else
     buffer = buffer + c

当然,你可以使用正则表达式,但我个人更倾向于寻求一个更简单的解决方案,即使它更具有hackish。正则表达式有时会很难读。

答案 3 :(得分:0)

eugene y的答案的另一种选择:

my $s = "abc[1,2,3].something.here,foo[10,6,34].somethingelse.here,def[1,2].another";
my @a = ($s =~ /[^,]+\[[\d,]*\]/g);
print join("\n", @a,"")

答案 4 :(得分:0)

这个问题让我有理由看一下我想要的Regexp::Grammars一段时间。以下代码段适用于您的输入:

use Regexp::Grammars;
use Data::Dump qw(dd);

my $input
    = 'abc[1,2,3].something.here,foo[10,6,34].somethingelse.here,def[1,2].another';

my $re = qr{
    <[tokens]> ** (,)  # comma separated tokens

    <rule: tokens>     <.token>*
    <rule: token>      \w+ | [.] | <bracketed>
    <rule: bracketed>  \[ <.token> ** (,) \]
}x;

dd $/{tokens}
    if $input =~ $re;

# prints
# [
#   "abc[1,2,3].something.here",
#   "foo[10,6,34].somethingelse.here",
#   "def[1,2].another",
# ]