19

我需要一个正则表达式来匹配整数值和浮点数(而浮点数有一个“。”作为分隔符)。这些数字总是在括号中,并且可能有一个前导“+”。

什么应该是有效的:

  • (1.0)
  • (1)
  • (9.9)
  • (10000000)
  • (+15)

什么应该是无效的:

  • 1.0 --- 因为没有括号
  • 5 --- 因为没有括号
  • (1,5) --- 因为“,”而不是“。”
  • (a) --- 因为不是数字
  • (1 5) --- 因为不止一个数
  • (1+5) --- 因为......好吧......只是模式失败了
  • [5] --- 因为括号错误
4

3 回答 3

44

这应该适用于大多数像正则表达式引擎的 perl:

/(\d+(?:\.\d+)?)/
于 2013-01-27T18:20:07.517 回答
23

不幸的是,当前接受的答案是有缺陷的(它将匹配“1a5”,但不会匹配“.5”)。所以我决定编写自己的 Regex,以及一个便宜的 Perl 脚本来测试它。

要求

正则表达式将匹配一个整数或浮点数,前面有一个 +/- 符号。我不关心 E 符号,所以我忽略了它。
nhahtdh 提到“(5.)和(.6)”:“5。” 在我看来不正确,尾随句号没有目的。但是,“.6”确实有效,因为前导句点表示正值 < 1(即,它是“0.6”的缩写)。
最初(?=.)是为了确保空白字符串不匹配。
作为奖励,我使用了嵌套组,以便您可以轻松提取数字的不同部分:

  • $1 = 整数
  • $2 = 整数部分
  • $3 = 带前导周期的小数部分
  • $4 = 小数部分

正则表达式

^(?=.)([+-]?([0-9]*)(\.([0-9]+))?)$

测试

$ perl -e 'use strict; use warnings; my $a = "1.0"; if ($a =~ /^(?=.)([+-]?([0-9]*)(\.([0-9]+))?)$/) { print "MATCH\nFloat:<$1>\n"; print defined $2 ? "Integer:<$2>\n" : "No integer\n"; print defined $4 ? "Fraction:<$4>\n" : "No fraction\n"; } else { print "NO MATCH\n"; }'
MATCH
Float:<1.0>
Integer:<1>
Fraction:<0>
$ perl -e 'use strict; use warnings; my $a = "1"; if ($a =~ /^(?=.)([+-]?([0-9]*)(\.([0-9]+))?)$/) { print "MATCH\nFloat:<$1>\n"; print defined $2 ? "Integer:<$2>\n" : "No integer\n"; print defined $4 ? "Fraction:<$4>\n" : "No fraction\n"; } else { print "NO MATCH\n"; }'
MATCH
Float:<1>
Integer:<1>
No fraction
$ perl -e 'use strict; use warnings; my $a = "9.9"; if ($a =~ /^(?=.)([+-]?([0-9]*)(\.([0-9]+))?)$/) { print "MATCH\nFloat:<$1>\n"; print defined $2 ? "Integer:<$2>\n" : "No integer\n"; print defined $4 ? "Fraction:<$4>\n" : "No fraction\n"; } else { print "NO MATCH\n"; }'
MATCH
Float:<9.9>
Integer:<9>
Fraction:<9>
$ perl -e 'use strict; use warnings; my $a = "10000000"; if ($a =~ /^(?=.)([+-]?([0-9]*)(\.([0-9]+))?)$/) { print "MATCH\nFloat:<$1>\n"; print defined $2 ? "Integer:<$2>\n" : "No integer\n"; print defined $4 ? "Fraction:<$4>\n" : "No fraction\n"; } else { print "NO MATCH\n"; }'
MATCH
Float:<10000000>
Integer:<10000000>
No fraction
$ perl -e 'use strict; use warnings; my $a = "+15"; if ($a =~ /^(?=.)([+-]?([0-9]*)(\.([0-9]+))?)$/) { print "MATCH\nFloat:<$1>\n"; print defined $2 ? "Integer:<$2>\n" : "No integer\n"; print defined $4 ? "Fraction:<$4>\n" : "No fraction\n"; } else { print "NO MATCH\n"; }'
MATCH
Float:<+15>
Integer:<15>
No fraction
$ perl -e 'use strict; use warnings; my $a = "1,5"; if ($a =~ /^(?=.)([+-]?([0-9]*)(\.([0-9]+))?)$/) { print "MATCH\nFloat:<$1>\n"; print defined $2 ? "Integer:<$2>\n" : "No integer\n"; print defined $4 ? "Fraction:<$4>\n" : "No fraction\n"; } else { print "NO MATCH\n"; }'
NO MATCH
$ perl -e 'use strict; use warnings; my $a = "a"; if ($a =~ /^(?=.)([+-]?([0-9]*)(\.([0-9]+))?)$/) { print "MATCH\nFloat:<$1>\n"; print defined $2 ? "Integer:<$2>\n" : "No integer\n"; print defined $4 ? "Fraction:<$4>\n" : "No fraction\n"; } else { print "NO MATCH\n"; }'
NO MATCH
$ perl -e 'use strict; use warnings; my $a = "1 5"; if ($a =~ /^(?=.)([+-]?([0-9]*)(\.([0-9]+))?)$/) { print "MATCH\nFloat:<$1>\n"; print defined $2 ? "Integer:<$2>\n" : "No integer\n"; print defined $4 ? "Fraction:<$4>\n" : "No fraction\n"; } else { print "NO MATCH\n"; }'
NO MATCH
$ perl -e 'use strict; use warnings; my $a = "1+5"; if ($a =~ /^(?=.)([+-]?([0-9]*)(\.([0-9]+))?)$/) { print "MATCH\nFloat:<$1>\n"; print defined $2 ? "Integer:<$2>\n" : "No integer\n"; print defined $4 ? "Fraction:<$4>\n" : "No fraction\n"; } else { print "NO MATCH\n"; }'
NO MATCH
$ perl -e 'use strict; use warnings; my $a = "5."; if ($a =~ /^(?=.)([+-]?([0-9]*)(\.([0-9]+))?)$/) { print "MATCH\nFloat:<$1>\n"; print defined $2 ? "Integer:<$2>\n" : "No integer\n"; print defined $4 ? "Fraction:<$4>\n" : "No fraction\n"; } else { print "NO MATCH\n"; }'
NO MATCH
$ perl -e 'use strict; use warnings; my $a = ".6"; if ($a =~ /^(?=.)([+-]?([0-9]*)(\.([0-9]+))?)$/) { print "MATCH\nFloat:<$1>\n"; print defined $2 ? "Integer:<$2>\n" : "No integer\n"; print defined $4 ? "Fraction:<$4>\n" : "No fraction\n"; } else { print "NO MATCH\n"; }'
MATCH
Float:<.6>
Integer:<>
Fraction:<6>
$ perl -e 'use strict; use warnings; my $a = ".5"; if ($a =~ /^(?=.)([+-]?([0-9]*)(\.([0-9]+))?)$/) { print "MATCH\nFloat:<$1>\n"; print defined $2 ? "Integer:<$2>\n" : "No integer\n"; print defined $4 ? "Fraction:<$4>\n" : "No fraction\n"; } else { print "NO MATCH\n"; }'
MATCH
Float:<.5>
Integer:<>
Fraction:<5>
$ perl -e 'use strict; use warnings; my $a = "1a5"; if ($a =~ /^(?=.)([+-]?([0-9]*)(\.([0-9]+))?)$/) { print "MATCH\nFloat:<$1>\n"; print defined $2 ? "Integer:<$2>\n" : "No integer\n"; print defined $4 ? "Fraction:<$4>\n" : "No fraction\n"; } else { print "NO MATCH\n"; }'
NO MATCH

如果有什么我忽略了,请告诉我。

添加

强制大括号是微不足道的,只需将整个东西包裹在 ESCAPE 括号中:

^\((?=.)([+-]?([0-9]*)(\.([0-9]+))?)\)$
于 2014-04-14T12:06:59.137 回答
-1

我不确定,但我认为接受的答案不会接受.6

my $float = qr/(\([-+]?\d*\.?\d+\))/;
my $test = "this is my +15.8 (-17.3) 0.9 (8) .7 -.6 string"
    . "(+5.8) -6.3 (0.9) 8 (.9) (-.16)";

while ($test =~ /$float/g) {
    printf("<$1>\n");
}

我从某个地方偷了这个图案。也许https://www.regular-expressions.info/floatingpoint.html

<(-17.3)>
<(8)>
<(+5.8)>
<(0.9)>
<(.9)>
<(-.16)>

更新:添加了括号。

于 2019-02-20T06:56:54.093 回答