我正在尝试使用正则表达式匹配所有逗号(后跟一个空格):,
在任何括号或方括号之外,即逗号不应包含在括号或方括号中。
目标字符串是A, An(hi, world[hello, (hi , world) world]); This, These
. 在这种情况下,它应该匹配第一个逗号和最后一个逗号(A
和An
、this
和之间的那些these
)。
因此,我可以拆分A, An(hi, world[hello, (hi , world) world]); This, These
为A
,An(hi, world[hello, (hi , world) world]); This
和These
,而不会因此导致括号/括号不平衡。
为此,单独使用正则表达式似乎很难。有没有其他方法可以解决这个问题?
我正在使用的正则表达式: , (?![^()\[\]]*[\)\]])
但是这个表达式将匹配其他不应该匹配的额外的两个逗号,
(第二个和第三个)。
虽然如果它与以下字符串匹配,它将匹配正确的逗号(分别为第一个):A, An(hi, world)
和A, An[hi, world]
但是如果括号和方括号相互包含,就会出现问题。
此链接中的更多详细信息:https : //regex101.com/r/g8DOh6/1
这里的问题是在这种情况下识别括号/括号的“平衡”对。这是一个众所周知的问题,有图书馆可以解决这个问题。
然后找到顶级匹配对、(...)
/[...]
和所有其他 - 并处理“else”。
一种方法,使用Regexp::Common
use warnings;
use strict;
use feature 'say';
use Regexp::Common;
my $str = shift // q{A, t(a,b(c,))u B, C, p(d,)q D,};
my @all_parts = split /$RE{balanced}{-parens=>'()[]'}/, $str;
my @no_paren_parts = grep { not /\(.*\) | \[.*\]/x } @all_parts;
say for @no_paren_parts;
这使用了一个很好的split属性来返回包含分隔符的列表,当分隔符模式中的正则表达式捕获时。†库中的正则表达式这样做,所以我们取回所有部分——字符串的“其余部分”以及正则表达式匹配的部分。分隔符包含成对的分隔符,而其他术语不能,通过构造,所以我通过它过滤掉它们。这打印
A, tu B, C, p q D,
括号/括号术语消失了,但是字符串的分割方式有点随意。
上面的内容有点“通用”,仅使用库来提取平衡对()
/[]
以及字符串的所有其他部分。但是我们也可以从字符串中删除这些模式
$str =~ s/$RE{balanced}{-parens=>'()[]'}//g;
留下来
A, 涂 B, C, pq D,
现在可以简单地用逗号分隔
my @terms = split /\s*,\s*/, $str;
say for @terms;
为了
A tu B C pq D
在这种情况下,这是所需的结果,如评论中所述。
另一个最著名的库,在许多方面更为基本,是 core Text::Balance
. 见肖恩的答案在这里,例如这篇文章和这一个和这一个的例子。
†一个例子。和
my $str = q(it, is; surely);
my @terms = split /[,;]/, $str;
一个进入it
is
surely
数组@terms
,而
my @terms = split /([,;])/, $str;
我们得到了@terms
所有:it
,
is
;
surely
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句