Regex 在Perl中使用正则表达式解析行

Regex 在Perl中使用正则表达式解析行,regex,git,perl,Regex,Git,Perl,所以我正在制作一个程序来统计git存储库,但是我在使用某个正则表达式时遇到了麻烦。基本上,我有一个字符串,如下所示: my $string = "5 2 gitc" my ($added, $removed) = $string =~ /([0-9]*) *([0-9]*) *[a-z]*/; 还有一个正则表达式,如下所示: my $string = "5 2 gitc" my ($added, $removed) = $string =~ /([0-9]*) *(

所以我正在制作一个程序来统计git存储库,但是我在使用某个正则表达式时遇到了麻烦。基本上,我有一个字符串,如下所示:

my $string = "5    2    gitc"
my ($added, $removed) = $string =~ /([0-9]*) *([0-9]*) *[a-z]*/;
还有一个正则表达式,如下所示:

my $string = "5    2    gitc"
my ($added, $removed) = $string =~ /([0-9]*) *([0-9]*) *[a-z]*/;
我的目标是将第一个数字存储为$added,第二个数字存储为$removed,但由于某些原因,$removed中没有存储任何值。因此,如果我使用print语句:

print "-$added $removed-\n";
输出如下所示:

-5 -

当我在regex101上测试正则表达式时,我的捕获组似乎工作得很好,所以我有点困惑为什么它不工作。有人看到我的正则表达式有问题吗?

正如Kyle在评论中指出的那样-如果必须有数字,那么使用
+
而不是
*
来减少搜索引擎必须搜索的可能匹配数。此外,由于
\s
匹配“空白”(定义为
[\\t\r\n\f]
),因此可以通过使用制表符而不是文本空格字符来消除制表符丢失匹配的可能性

使用
\s
匹配空格还可以释放文本空格字符,以帮助在正则表达式本身中进行格式化。为此,使用“扩展模式”regexs,在规范末尾添加一个
/x

最后,作为一般规则,在分配给这样的变量之前,测试是否匹配成功

my $string = "5    2    gitc";
if ($string =~ /(\d+) \s+ (\d+) [a-z]+/x)  {
    my ($added, $removed) = ($1, $2);
}
else
    print "Failed match\n";
}

正如凯尔在评论中指出的那样——如果数字必须在那里,那么使用
+
而不是
*
来减少搜索引擎必须搜索的可能匹配项的数量。此外,由于
\s
匹配“空白”(定义为
[\\t\r\n\f]
),因此可以通过使用制表符而不是文本空格字符来消除制表符丢失匹配的可能性

使用
\s
匹配空格还可以释放文本空格字符,以帮助在正则表达式本身中进行格式化。为此,使用“扩展模式”regexs,在规范末尾添加一个
/x

最后,作为一般规则,在分配给这样的变量之前,测试是否匹配成功

my $string = "5    2    gitc";
if ($string =~ /(\d+) \s+ (\d+) [a-z]+/x)  {
    my ($added, $removed) = ($1, $2);
}
else
    print "Failed match\n";
}
为什么不

my ($added, $removed) = split ' ', $string;
为什么不

my ($added, $removed) = split ' ', $string;

那里可能有制表符吗?当我在本地运行这两行时(确保$string中的空格字符),它就可以工作了。i、 e.我得到“-5 2-”这些数字是可选的,还是一定要在那里?如果它们总是在那里,那么尝试使用
+
而不是
*
,比如:
/([0-9]+)+([0-9]+)+[a-z]+/
。与
+
@Marty匹配的方法很少,这是一个非常好的检查方法。修改我的建议:
/([0-9]+)[\t]+([0-9]+)[\t]+[a-z]+/
是的,它一直是一个制表符。谢谢你们两位的帮助@Marty:您可能需要在其中添加一个
\s+
,例如:
/(\d+)\s+(\d+)\s+\w+/x
(使用
\w
表示单词字符-大写和小写等)。是否可能有制表符?当我在本地运行这两行时(确保$string中的空格字符),它就可以工作了。i、 e.我得到“-5 2-”这些数字是可选的,还是一定要在那里?如果它们总是在那里,那么尝试使用
+
而不是
*
,比如:
/([0-9]+)+([0-9]+)+[a-z]+/
。与
+
@Marty匹配的方法很少,这是一个非常好的检查方法。修改我的建议:
/([0-9]+)[\t]+([0-9]+)[\t]+[a-z]+/
是的,它一直是一个制表符。谢谢你们两位的帮助@马蒂:你可能需要在里面加一个
\s+
,比如:
/(\d+)\s+(\d+)\s+\w+/x
(使用
\w
表示单词字符-大写和小写,等等)。