Regex 为什么我的正则表达式在数字以0结尾时失败?
这是一个非常基本的正则表达式问题,但由于我似乎不明白为什么在某些情况下比赛会失败,我想我会发布它,看看是否有人能指出我遗漏了什么 我试图从表单的字符串中提取两组数字:Regex 为什么我的正则表达式在数字以0结尾时失败?,regex,perl,Regex,Perl,这是一个非常基本的正则表达式问题,但由于我似乎不明白为什么在某些情况下比赛会失败,我想我会发布它,看看是否有人能指出我遗漏了什么 我试图从表单的字符串中提取两组数字: 12309123098_102938120938120938 1321312_103810312032123 123123123_10983094854905490 38293827_1293120938129308 我使用以下代码来处理每个字符串: if($string && $string =~ /^(\d)
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
有没有关于为什么这些失败而其他成功的想法?提前感谢您的帮助 分组中不应包括
+
:
分组中不应包括
^(\d+)\ud+$
而不是^(\d)+\ud+$
+
:
^(\d+)(\d+)$
而不是^(\d+)+\d+$
因为在第二个字符串的末尾有0
,(\d)+
只在$N
变量中放置最后一个匹配项,字符串“0”
相当于false。因为在第二个字符串的末尾有0
($N
变量中放入最后一个匹配项,字符串“0”
相当于false。这是UnicorAddict和ZyX的答案的附加内容:您想匹配什么
如果您试图匹配“\ux”的左右顺序,则unicorn addict是正确的,并且您的正则表达式必须是^(\d+)\ux(\d+)$
。此外,您还可以完全去掉第一个限定符和'IsIntrger()`函数-您已经知道它是一个整数-它匹配(\d+)
如果您试图匹配每个中的最后一个数字,并且想知道它为什么失败,那么这是第一次签入IsInteger()
(If($intger&&
)。它是冗余的(您知道它是一个整数),并且在0上失败,因为正如ZyX所指出的,它的计算结果为false
但同样的情况也适用于:
if ($string =~ /^(\d)+_(\d)+$/) {
print "success ('$1','$2')";
} else {
print "fail\n";
}
这将输出
success('8','8')
给定输入12309123098_102938120938120938
这是UnicorAddict和ZyX的答案的一个附加项:您想匹配什么
如果您试图匹配'.''左右的序列,unicorn addict是正确的,并且您的正则表达式需要是^(\d+)\ud+$
。此外,您可以完全去掉第一个限定符和'IsIntrger()`函数-您已经知道它是一个整数-它匹配了(\d+)
如果您试图匹配每个中的最后一个数字,并且想知道它为什么失败,那么这是第一次签入IsInteger()
(If($intger&&
)。它是冗余的(您知道它是一个整数),并且在0上失败,因为正如ZyX所指出的,它的计算结果为false
但同样的情况也适用于:
if ($string =~ /^(\d)+_(\d)+$/) {
print "success ('$1','$2')";
} else {
print "fail\n";
}
这将输出
success('8','8')
给定输入12309123098_102938120938120938
如有疑问,请检查正则表达式实际捕获的内容
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
中(考虑到主循环中的初始正则表达式,这似乎是不必要的),您测试的是真值,而不是更具体的值,例如定义的或长度。例如,零是有效的整数,但为假。如果有疑问,请检查正则表达式实际捕获的内容
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
中(考虑到主循环中的初始正则表达式,这似乎是不必要的),您正在测试的是真实性,而不是更具体的东西,例如定义的或长度。例如,零是一个有效的整数,但却是错误的。许多人对您的正则表达式发表了评论,但您在中遇到的问题是integer
(您的示例确实不需要它)。您检查了“真实性”当您确实要检查以下各项时:
不过,您不需要该子例程中的大部分基础结构:
sub IsInteger {
defined $_[0] && $_[0] =~ /^\d+$/
}
很多人都对您的正则表达式发表了评论,但您的中存在的问题是Integer
(您的示例中确实不需要它)。您在真正想检查以下内容时检查了“真理”:
不过,您不需要该子例程中的大部分基础结构:
sub IsInteger {
defined $_[0] && $_[0] =~ /^\d+$/
}
你需要IsInteger函数做什么?你的第一个正则表达式只会把一系列数字放在$1
和$2
上,无需测试。只需将整个if
替换为if($string=~/^(\d+){print“success('$1','$2')”;}否则{print“fail”}
,为什么要写if($string)
?你不需要它。@ZyZ-很好。我继续更新了这个函数。你需要IsInteger函数做什么?你的第一个正则表达式只会在$1
和$2
上放置一系列数字,无需测试。只需将整个if
替换为if($string=~/^(\d+)(\d+)/){print“success”('1','2')“;}否则{print“fail”}
为什么要编写if($string)
?您不需要它。@ZyZ-很好。我继续更新了函数。@ZyX-很好地解释了失败的原因。感谢您帮助我理解问题!@ZyX-很好地解释了失败的原因。感谢您帮助我理解问题!+1用于定义,-1用于最后一部分:虽然您在技术上是正确的,但实际上解包子程序参数可以使代码更加清晰,我认为,当Perl对于新手来说已经很难阅读时,阻止有用的最佳实践并不是一个好主意。解包子程序参数并不总是使代码更清晰或更好。这是一种无法从中获得额外价值的情况它。当你不需要的时候,你正在做更多的实际工作,并且创建更多的内容来阅读。如果你知道Perl,我的版本中没有什么是神秘的。如果你不知道