【问题标题】:Using regular expressions to parse a line in Perl在 Perl 中使用正则表达式解析一行
【发布时间】:2016-04-08 21:32:20
【问题描述】:

所以我正在制作一个统计 git 存储库的程序,但我无法让某个正则表达式正常工作。基本上,我有一个看起来像这样的字符串:

my $string = "5    2    gitc"

还有一个如下所示的正则表达式:

my ($added, $removed) = $string =~ /([0-9]*) *([0-9]*) *[a-z]*/;

我的目标是将第一个数字存储为 $added,第二个数字存储为 $removed,但由于某种原因,$removed 中没有存储任何值。所以如果我使用 print 语句:

print "-$added $removed-\n";

输出如下:

-5 -

当我在正则表达式 101 上测试该正则表达式时,我的捕获组似乎工作正常,所以我有点难过它为什么不起作用。谁能看到我的正则表达式有问题?

【问题讨论】:

  • 那里可能有制表符吗?当我在本地运行这两行时(确保 $string 中的空格字符)它可以工作。即我得到“-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 表示'单词字符——大小写等)。

标签: regex git perl


【解决方案1】:

正如 Kyle 在 cmets 中指出的那样 - 如果数字 必须 存在,则使用 + 而不是 * 来减少 RE 引擎必须搜索的可能匹配的数量。此外,由于\s 匹配“空白”(将here 定义为[\ \t\r\n\f]),因此您可以通过使用它而不是文字空格字符来避免制表符导致匹配失败。

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

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

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

【讨论】:

    【解决方案2】:

    为什么不直接

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

    【讨论】:

      猜你喜欢
      • 2010-09-05
      • 1970-01-01
      • 1970-01-01
      • 2013-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-28
      相关资源
      最近更新 更多