这是一个非常基本的正则表达式问题,但由于我似乎不能弄清楚为什么在某些情况下匹配会失败,所以我想发布它,看看是否有人能指出我遗漏了什么。
我正在尝试从以下形式的字符串中提取两组数字:
12309123098_102938120938120938
1321312_103810312032123
123123123_10983094854905490
38293827_1293120938129308
我使用以下代码来处理每个字符串:
if($string && $string =~ /^(\d)+_(\d)+$/) {
if(IsInteger($1) && IsInteger($2)) { print "success ('$1','$2')"; }
else { print "fail"; }
}
其中,IsInterger()函数如下所示:
sub IsInteger {
my $integer = shift;
if($integer && $integer =~ /^\d+$/) { return 1; }
return;
}
此函数似乎在大多数情况下都有效,但在以下情况下由于某些原因而失败:
1287123437_1268098784380
1287123437_1267589971660
有什么想法可以解释为什么这些失败了,而其他成功了呢?提前感谢您的帮助!
发布于 2010-04-17 17:18:18
这是对独角兽成瘾者和ZyX的回答的补充:你想匹配什么?
如果你正在尝试匹配'_‘左右的序列,独角兽成瘾者是正确的,并且你的正则表达式需要是^(\d+)_(\d+)$
。此外,您还可以完全摆脱第一个限定符和‘IsIntrger()’函数-您已经知道它是一个整数-它匹配(\d+)
if ($string =~ /^(\d+)_(\d+)$/) {
print "success ('$1','$2')";
} else {
print "fail\n";
}
如果您试图匹配每一项中的最后一位数字,并且想知道为什么失败,那么这是第一次在IsInteger()
( if($intger &&
)中进行检查。无论如何,它都是多余的(你知道它是一个整数),并且在0上失败,因为,正如ZyX所指出的-它的计算结果为false。
不过,同样的事情也适用:
if ($string =~ /^(\d)+_(\d)+$/) {
print "success ('$1','$2')";
} else {
print "fail\n";
}
在给定输入12309123098_102938120938120938
的情况下,这将输出success ('8','8')
发布于 2010-04-17 17:03:09
因为在第二个字符串的末尾有0
,所以(\d)+
只在$N
变量中放入最后一个匹配项,string "0"
等同于false。
发布于 2010-04-17 17:38:21
如果不确定,请检查您的正则表达式实际捕获的内容。
use strict;
use warnings;
my @data = (
'1321312_103810312032123',
'123123123_10983094854905490',
);
for my $s (@data){
print "\$1=$1 \$2=$2\n" if $s =~ /^(\d)+_(\d)+$/;
# Output:
# $1=2 $2=3
# $1=3 $2=0
}
您可能打算采用这两种方法中的第二种方法。
(\d)+ # Repeat a regex group 1+ times,
# capturing only the last instance.
(\d+) # Capture 1+ digits.
此外,无论是在主循环中还是在IsInteger
中(考虑到主循环中的初始正则表达式,这似乎都是不必要的),您要测试的是真值,而不是更具体的东西,比如defined
或length
。例如,零是一个有效的整数,但却是假的。
https://stackoverflow.com/questions/2659201
复制