为什么我的正则表达式无法匹配版本号?

3
我正在遇到一个与网络脚本有关的Perl正则表达式匹配问题,我已经将这种行为放入了一个小片段中。
请看以下适用于Debian中Perl 5.10.0的Perl代码片段:
#!/usr/bin/perl
use warnings;
use strict;

my $line = "Version: 0\r\n";
my($version) = $line =~ m/^Version:(\s\d+)\r\n$/;
print "1st failed \n" if not $version; 
($version) = $line =~ m/^Version:\s(\d+)\r\n$/;
print "2nd failed \n" if not $version; 
($version) = $line =~ m/^Version:\ (\d+)\r\n$/;
print "3th failed \n" if not $version; 

使用以下输出:

2nd failed
3th failed 

显然,第一种和第二种之间唯一的区别是将空格从提取的模式中移出,理论上不应该修改正则表达式,只是返回的部分不同。
我不明白为什么第二种和第三种不能像第一种一样工作。
编辑: 如果在$version is not the same script中删除括号,则不会得到匹配的结果,而是得到操作的布尔结果,要获得匹配的结果,需要在一个一元组中接收它(只有一个字符串进行匹配)。
2个回答

12

问题在于你正在测试布尔值的真假,因为在后两种情况下,你提取的是一个字符串值,其值为false(字符串'0')。试试这个:

$line = "Version: 0\r\n";
my $version;
($version) = $line =~ m/^Version:(\s\d+)\r\n$/;
print "1st failed \n" unless defined $version;
($version) = $line =~ m/^Version:\s(\d+)\r\n$/;
print "2nd failed \n" unless defined $version;
($version) = $line =~ m/^Version:\ (\d+)\r\n$/;
print "3th failed \n" unless defined $version;

你绝对是正确的,使用“Version: 1”就不会发生这种情况,匹配的模式是字符串“0”,其布尔结果为false。我之前怎么没注意到呢? :| - Arkaitz Jimenez
1
你可能没有注意到,因为第一个匹配项也有一个 0。不同之处在于,第一个匹配项捕获了 [ ]0,而空格的存在使得 字符串被评估为 true。这就是为什么我至少没有立即看到它的原因。 - Telemachus
如果将代码写成这样:"print "failed\n" unless ($version) = $line =~ ..." 也许会起作用。 - Brad Gilbert

2

您没有测试匹配运算符。如果您想查看匹配失败的情况,请测试匹配:

 if( $line =~ m/(...)/ ) {
    $version = $1;
    }

在调试过程中,您至少可以检查一下以将问题缩小到出现故障的部分。

使用不同的数据进行操作,例如:

 Version: 1\r\n

如果版本为0,则会显示不同的行为,你可能已经注意到了这一点,如果失败了。这可能在你的脑海中点亮了一些灯泡 :)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接