捕捉多种模式

时间:2017-06-26 11:12:04

标签: regex perl

我正在尝试将字符串与多个模式匹配,并将捕获存储在数组中。

输入可以是以下之一:

-fnospacebetween
   -f textwithspacebefore
@nospacebetween
  @ textwithspacebefore

正则表达式应该在-f@之后捕获字符串。在-f@之前,-f@与字符串之间允许有空格。
我考虑使用|分割的正则表达式,但我不知道为什么当我按特定顺序使用两个正则表达式时它没有抓住我的输入。
单个案例场景按预期工作:

my $text = '@anystring' ;

if( $text =~ /^\s*\@\s*(\S*)/)
{
    print "\n $1";
}



my $text = '-fanystring' ;

if( $text =~ /^\s*-f\s*(\S*)/)
{
    print "\n $1";
}

但是当我尝试在一个正则表达式中使用这两个时,我得到一个Use of unitialized...

my $text = '@anystring' ;

if( $text =~ /^\s*-f\s*(\S*)|^\s*\@\s*(\S*)/)
{
    print "\n $1";
}

但是使用此变体,它可以正常工作:

my $text = '@anystring' ;
if( $text =~ /^\s*\@\s*(\S*)|^\s*-f\s*(\S*)/)
{
    print "\n1:  $1";
}

为什么在切换订单时它能正确匹配?

2 个答案:

答案 0 :(得分:1)

  

为什么在切换订单时它能正确匹配?

这个正则表达式

/^\s*\@\s*(\S*)|^\s*-f\s*(\S*)/

将捕获到$1$2,具体取决于匹配的替代方案。但是你只打印$1,如果它是匹配的第二个选择,那就是undef

我建议你使用它,它只有一次捕获,并且仅对模式中可变的部分使用替换

/^\s*(?:\@|-f)\s*(\S*)/

答案 1 :(得分:0)

你的正则表达式的另一个潜在问题是它也匹配

-f -fanother-flag
-@ -@another-flag

也就是说,如果没有给第一个标志赋予参数,\S*将匹配任何后续标志。如果参数是可选的,则最好使用\s*([^-]?\S*);如果是必需的话,最好使用\s*([^-]\S*)。这仍然假设flag参数不能以连字符开头。