为什么这个正则表达式不匹配Perl?

时间:2014-06-24 14:00:47

标签: regex string perl

我有一个字符串,可以读取这样的内容(虽然并非总是如此,但数字可能会有所不同)。

Board Length,45,inches,color,board height,8,inches,black,store,wal-mart,Board weight,20,dollars

我试图匹配Board Length这个正则表达式后面的45。

if ($string =~/Board Length,(\d+\.\d+)/){

    print $string;

}

格式错误了吗?我认为d +会根据需要匹配尽可能多的数字。将匹配文字'。',并且d +将匹配小数点后的任何数字(如果有的话)。

4 个答案:

答案 0 :(得分:2)

正如您所说,十进制.和后续数字是必需的。因此(\.\d+)?使其成为可选项,

if ($string =~/Board Length,(\d+(?:\.\d+)?)/)

答案 1 :(得分:2)

你应该匹配什么是完全正确的。但是,没有'?'你指定所有这些部分都必须存在。

\d+\.\d+

这意味着“1个或更多数字,期间,1个或更多数字”

1.5,253333.7,0.0都将匹配。但是,您的示例使用45,没有“。”在其中,也不是后来的数字。您的问题有一些解决方案,mpapac上面已经说明了最全面的证明。允许小数和后续数字是可选的。

(\.\d+)?

这样的问题是在它周围放一个()会使它成为另一个捕获组。你可能想要也可能不想要这个。将?:放在里面意味着“将它作为一个组使用,但不要捕获它”。因此:

(?:\.\d+)?

另一个选项是不进行分组,而是使小数本身可选,小数点后面的数字为ZERO或更多,而不是一个或多个。这看起来像这样:

\d+\.?\d*

答案 2 :(得分:1)

您没有打印捕获的内容。您正在打印我们不知道它是什么的$_

if ($string =~/Board Length,(\d+\.\d+)/){
    print $_;
}

我认为你想要的是:

if ($string =~/Board Length,(\d+\.\d+)/){
    print $1;
}

答案 3 :(得分:0)

您有以下表达式:

$string =~/Board Length,(\d+\.\d+) /

你的字符串是:

Board Length,45,inches

字符串Board Length将匹配模式Board Length,。但是,我们的其余模式是匹配一个或多个数字,后跟一个句点后跟一个或多个数字。这与字符串45不匹配。那里没有小数。

问题是你想要匹配什么。例如,如果数字用逗号包围,则可以执行以下操作:

$string =~ /Board Length,([^,]+),/;
my $number = $1;

[^,]表示不是逗号。您将逗号后的所有内容捕获到下一个逗号。这样您就可以捕获4545.32甚至4.5e+10。只是两个逗号之间的任何内容。

请注意,您使用$1作为第一个捕获组,而不是$_

另一种方法是使用非贪婪匹配:

$string =~ /Board Length,(.+?),/;
my $number = $1;

如果捕获的内容不是数字,会发生什么?您可以使用looks_like_number中的Scalar::Util函数(已经包含在Perl发行版中很长时间)来测试它。:

use Scalar::Util    qw(looks_like_number);

my $string = "Board Length,Extra long,feet,...";
...
$string =~ /Board Length,(.+?),/;
my $number = $1;

if ( looks_like_number( $number ) ) {
    print "$number is a number\n";
}
else {
    print "Nope. $number isn't a number\n";
}