Perl分裂和正则表达式

时间:2011-12-12 21:47:38

标签: regex perl split

我有以下字符串:

'100% California Grown Olives, Water, Salt And Ferrous Gluconate (An,Iron, Derivative),asasd, sadasda'

我试图将其拆分为/,/,但只有当不在括号内时,例如,在这种情况下,结果应为:

100% California Grown Olives
Water
Salt And Ferrous Gluconate (An,Iron, Derivative)
asasd
sadasda

感谢,

3 个答案:

答案 0 :(得分:11)

@result = split(m/,(?![^()]*\))/, $subject);

仅当下一个括号(如果有)不是右括号时,才会对逗号进行分割。正如Jack Maney所说,如果可能出现嵌套括号,这可能会导致失败。

<强>解释

,       # Match a comma.
(?!     # Assert that it's impossible to match...
 [^()]* # any number of non-parenthesis characters
 \)     # followed by a closing parenthesis
)       # End of lookahead assertion

答案 1 :(得分:1)

首先,你需要决定什么是parens,以及它们是否可以嵌套。 (对于这个答案,我会假设他们可以)。然后,您需要从文本中删除这些paren块并将其替换为占位符:

my @parens;
$str =~ s/( \( (?: (?0)|[^()] )* \) )/push @parens, $1; "PARENS_$#parens"/gex;

所以现在你留下的东西看起来像:

'100% California Grown Olives, Water, Salt And Ferrous Gluconate PAREN_0,asasd,
sadasdas.'

现在将它拆分为逗号很​​简单。然后在每个拆分件上扫描PAREN_\d+个令牌,并将其替换为@parens阵列中的值。您可能需要使用更独特的占位符名称,具体取决于您的源内容。

类似的东西:

s/PARENS_(\d+)/$parens[$1]/ge for my @segs = split /,\s*/ => $str;

say for @segs;

对于示例字符串:

my $str = "foo (b,a,r), baz (foo, (bar), baz), biz";

打印:

foo (b,a,r)
baz (foo, (bar), baz)
biz

答案 2 :(得分:0)

您可能会发现为您想要匹配的内容构建正则表达式更容易,而不是您想要删除的内容。 (这假设您不希望限制匹配数。)