如何捕获正则表达式交替的匹配组与拆分?

时间:2017-03-27 09:01:34

标签: regex perl

我有一个字符串

my $foo = 'one#two#three!four#five#six';

我要从中提取由#!分隔的部分。使用split

这很容易
my @parts = split /#|!/, $foo;

另外一个要求是我还需要捕捉感叹号。所以我试过

my @parts = split /#|(!)/, $foo;

然而,这会返回undef值或感叹号(在拆分规范中也明确说明)。

因此,我使用undef

清除了不需要的grep
my @parts = grep { defined } split /#|(!)/, $foo;

这就是我想要的。

然而我想知道我是否可以改变正则表达式,这样我就不必再调用grep

2 个答案:

答案 0 :(得分:5)

当您使用split时,一旦找到匹配项,您可能不会省略空的捕获(因为匹配中的捕获总是与正则表达式中定义的一样多)。不过,您可以在此处使用匹配方法:

my @parts = $foo =~ /[^!#]+|!/g;

这样,您将匹配除!#以外的一个或多个字符(带有[^!#]+替代品)或感叹号,多次(/g

答案 1 :(得分:2)

使用"空字符串后跟感叹号或空字符串,前面带有感叹号"取代你的第二个选择:

my @parts = split /#|(?=!)|(?<=!)/, $foo;

演示:https://ideone.com/6pA1wx