这是一个非常基本的正则表达式问题,但由于我似乎无法弄清楚为什么匹配在某些情况下会失败,我想我会发布它以查看是否有其他人可以指出我缺少的东西。< / p>
我正在尝试从表单的字符串中取出2组数字:
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
关于为什么这些失败而其他人成功的任何想法?在此先感谢您的帮助!
答案 0 :(得分:3)
因为在第二个字符串的末尾有0
,(\d)+
只在$N
变量中放置最后一个匹配,所以字符串"0"
等同于false。 / p>
答案 1 :(得分:3)
这是unicornaddict和ZyX答案的附加内容:你想要匹配什么?
如果您尝试匹配“_”左右两侧的序列,则独角兽上瘾者是正确的,您的正则表达式需要为^(\d+)_(\d+)$
。此外,你可以完全摆脱第一个限定符和'IsIntrger()`函数 - 你已经知道它是一个整数 - 它匹配(\ d +)
if ($string =~ /^(\d+)_(\d+)$/) {
print "success ('$1','$2')";
} else {
print "fail\n";
}
如果您尝试匹配每个数字中的最后一个数字,并想知道它失败的原因,那么这是IsInteger()
(if($intger &&
)中的第一次检查。无论如何它都是多余的(你知道它是一个整数)并且在0上失败,因为正如ZyX所说 - 它的计算结果为假。
但同样适用:
if ($string =~ /^(\d)+_(\d)+$/) {
print "success ('$1','$2')";
} else {
print "fail\n";
}
如果输入success ('8','8')
12309123098_102938120938120938
答案 2 :(得分:3)
如有疑问,请检查您的正则表达式实际捕获的内容。
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
中(考虑到主循环中的初始正则表达似乎是不必要的),你正在测试真理而不是更具体的东西,例如{{1} }或defined
。例如,零是一个有效的整数但是错误。
答案 3 :(得分:0)
分组中不应包含+
:
^(\d+)_(\d+)$
代替^(\d)+_(\d)+$
答案 4 :(得分:0)
很多人都对您的正则表达式进行了评论,但您在IsInteger
中遇到了问题(您的示例中并不需要这个问题)。当您确实要检查defined时,您检查了“真相”:
sub IsInteger {
my $integer = shift;
if( defined $integer && $integer =~ /^\d+$/) { return 1; }
return;
}
您不需要该子例程中的大部分基础结构:
sub IsInteger {
defined $_[0] && $_[0] =~ /^\d+$/
}