1

嗨,我正在尝试为货币创建一个正则表达式。小数点后的部分工作正常。但是我在第一部分遇到问题。我希望它接受以下数字:

00.12
0.12
00
0

但不是带有前导零的数字,例如:

0012.12
00023

这就是我所拥有的,但我无法让它工作

^([1-9][0-9]*|0|00)+(\.(\d){2})?$
4

3 回答 3

1

您只需从字符串的前面检查 1 个或多个零,后跟 1 到 9 位数字。这种逻辑意味着所需的正则表达式模式可以保持非常简单。

代码:(演示

$tests = [
    '00.12',
    '0.12',
    '00',
    '0',
    '0012.12',
    '00023',
];
foreach ($tests as $test) {
    echo $test . (preg_match('~^0+[1-9]~', $test) ? ' fail' : ' pass') . "\n";
}

输出:

00.12 pass
0.12 pass
00 pass
0 pass
0012.12 fail
00023 fail

要更正您的完整模式,您不需要第一组的量词:(演示

echo preg_match('~^(?:[1-9]\d*|0{1,2})(?:\.\d{2})?$~', $test) ? ' pass' : ' fail'

但老实说,为什么不直接将它们转换为浮点数而不是拒绝带有前导零的值呢?(演示)我可能会这样做以获得更好的用户体验。或者也许只是用 标准化输入数字number_format()。(演示)在这里听起来可能像一个XY问题。

于 2020-04-27T03:11:03.527 回答
1

您需要删除+第一个捕获组上的量词——它将允许多次重复0or 00。换句话说,000, 0000,00000等将被视为有效的字符串的前导部分。分组允许三种类型中的任何一种。所以一个正则表达式,如

^(0{1,2}|[1-9]\d*)([.]\d\d)?$

将实现您的目标。

https://regex101.com/r/Tb1x6x/2/

于 2020-04-27T02:41:12.337 回答
0

[已编辑]

现在我的回答符合真正的要求:

^(0{1,2}|([1-9][0-9]*))(?:\.[0-9]{2})?$

你可以在这里试试这个: https ://regex101.com/r/8KJhk3/5

于 2020-04-27T03:03:46.527 回答