嗨,我正在尝试为货币创建一个正则表达式。小数点后的部分工作正常。但是我在第一部分遇到问题。我希望它接受以下数字:
00.12
0.12
00
0
但不是带有前导零的数字,例如:
0012.12
00023
这就是我所拥有的,但我无法让它工作
^([1-9][0-9]*|0|00)+(\.(\d){2})?$
您只需从字符串的前面检查 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问题。
您需要删除+第一个捕获组上的量词——它将允许多次重复0or 00。换句话说,000, 0000,00000等将被视为有效的字符串的前导部分。分组允许三种类型中的任何一种。所以一个正则表达式,如
^(0{1,2}|[1-9]\d*)([.]\d\d)?$
将实现您的目标。
[已编辑]
现在我的回答符合真正的要求:
^(0{1,2}|([1-9][0-9]*))(?:\.[0-9]{2})?$
你可以在这里试试这个: https ://regex101.com/r/8KJhk3/5