我有一个看起来像这样的字符串:
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
但是对评论的拆分不会有效,所以我的下一个想法是首先用方括号替换位于方括号之间的逗号,这样我就可以在逗号上拆分,然后在事后替换。
我尝试过几种方法但收效甚微..有什么建议吗?
答案 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",
# ]