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,我的版本中没有什么是神秘的。如果你不知道