如何在 Perl 正则表达式中捕捉一个点?

How to catch a dot in Perl regex?

我正在尝试执行这行代码:

  my $test = 'test .15oz test';
  $test =~ /([\d]+)([\.]?[\d]+)*oz\b/;
  print("test=\n");

这个输出是:

  test=15

我想抓住那个点。我究竟做错了什么? 最好的办法是抓到 0.15,但现在我连一个点都抓不到。

任何帮助从 regex 获得 0.15 的帮助将不胜感激,因此:

0.15 -> 0.15

.15 -> 0.15

..15 -> 0.15

0.0.0.15 -> 0.15

000.15 -> 0.15

15 -> 15

我也试过:

$test =~ /([\d]+)(\.?[\d]+)*oz\b/;
$test =~ /([\d]+)([.]?[\d]+)*oz\b/;

但没有成功。仍然得到“15”。

您正在使用第一个捕获组。在您的模式 ([\d]+)([\.]?[\d]+)*oz\b 中,第一个捕获组匹配一个或多个数字。要捕获 oz 之前的整个浮点数或整数,请使用

$test =~ /(\d*\.?\d+)oz\b/;
          ^         ^

其中 \d*\.?\d+ 将匹配 0+ 个数字、一个可选的点(注意它在字符 class 之外转义)和 1+ 个数字。

您要匹配的字符串被

匹配
(?:\d+(?:\.\d+)?|\.\d+)oz

(Wiktor Stribiżew 发布的内容更短,但效率低得多。)

所以你想要

if ( my ($match) = $test =~ /(\d+(?:\.\d+)?|\.\d+)oz/ ) {
   say $match;
}

如果您输入 .15..15,则您不可能匹配 0.15。只需独立于匹配项修复字符串。

$match = "0".$match if $match =~ /^\./;

同样,修剪前导零最好在匹配之外完成。

$match =~ s/^0+(?!\.)//;

加在一起,我们得到

if ( my ($match) = $test =~ /(\d+(?:\.\d+)?|\.\d+)oz/ ) {
   $match =~ s/^0+(?!\.)//;
   $match = "0".$match if $match =~ /^\./;
   say $match;
}