0

我遵循 Perl 脚本从日志中提取数字。?:当我在变量中定义子模式时,似乎非捕获组不起作用。只有当我在 regex-pattern 或$number.

#!/usr/bin/perl
use strict;
use warnings;

my $number = '(:?-?(?:(?:\d+\.?\d*)|(?:\.\d+))(?:[Ee][+-]?\d+)?)';
#my $number = '-?(?:(?:\d+\.?\d*)|(?:\.\d+))(?:[Ee][+-]?\d+)?';

open(FILE,"file.dat") or die "Exiting with: $!\n";
while (my $line = <FILE>) {
        if ($line =~ m{x = ($number). y = ($number)}){
        print "\$1= $1\n";
        print "\$2= $2\n";
        print "\$3= $3\n";
        print "\$4= $4\n";
    };
}
close(FILE);

此代码的输出如下所示:

$1= 12.15
$2= 12.15
$3= 3e-5
$4= 3e-5

对于以下输入:

asdf x = 12.15. y = 3e-5 yadda

那些翻倍的输出是不希望的。

这是因为样式与正则表达式m{}的常规模式相反吗?m//我只知道在我的正则表达式中获取变量(子字符串)的前一种风格。我只是注意到这一点用于反向引用,所以元字符可能还有其他差异吗?

4

2 回答 2

2

您用于正则表达式的分隔符不会导致任何问题,但以下是:

(:?-?(?:(?:\d+\.?\d*)|(?:\.\d+))(?:[Ee][+-]?\d+)?)
 ^^
Notice this isn't a capturing group, it is an optional colon :

可能是拼写错误,但它造成了麻烦。

编辑:看起来这不是一个拼写错误,我替换了正则表达式中的变量,我得到了这个:

x = ((:?-?(?:(?:\d+\.?\d*)|(?:\.\d+))(?:[Ee][+-]?\d+)?)). y = ((:?-?(?:(?:\d+\.?\d*)|(?:\.\d+))(?:[Ee][+-]?\d+)?))
    ^^           first and second group               ^^      ^^    third and fourth grouop                     ^^

如您所见,第一个和第二个捕获组正在捕获完全相同的东西,第三个和第四个捕获组也在发生同样的事情。

于 2013-09-03T09:16:51.790 回答
0

你会踢自己...

您的正则表达式显示为:

capture {
 maybe-colon
 maybe-minus
 cluster {     (?:(?:\d+\.?\d*)|(?:\.\d+))
  cluster {    (?:\d+\.?\d*)
   1+ digits
   maybe-dot
   0+ digits
  }
  -or-
  cluster {    (?:\.\d+)
   dot
   1+digits
  }
 }
 maybe cluster {
   E or e
   maybe + or -
   1+ digets
 }             (?:[Ee][+-]?\d+)?
}

...这就是你要找的。

但是,当您执行实际的正则表达式时,您会:

$line =~ m{x = $number. y = $number})

(花括号会分散注意力......如果指定了mor ,您可以使用任何 \W s

这要问的是在capture中定义的任何正则表达式$number是......它本身就是一个capture......因此$1并且$2是同一件事。

$number只需从其中一个或 regexp 行中删除捕获大括号。

于 2013-09-03T13:19:05.477 回答