还在学习正规表达!我的正则表达式百分比(不遵守100限制):
^(?<int>[1-9][0-9]*|[0])(?<dec>\.[0-9]+)?\%?$
此应该允许:
[1-9]
以不同于0的数字开头。不允许使用“004.34”等百分比。[0-9]*
...后跟0到9之间的任何数字|[0]
或以单个0 ...将此组捕获为“int”组。然后:
(?<dec>\.[0-9]+)?
一个可选组,只有在0到9之间至少有一个数字后才允许一个点。我不想让人输入,即“33”。假设我是对的,请测试:
preg_match('/^(?<int>[1-9][0-9]*|[0])(?<dec>\.[0-9]+)?\%?$/i', '0.32%', $result);
给我这个结果,这实际上是正确的,但是:
Array
(
[0] => 0.32%
[int] => 0
[1] => 0
[dec] => .32
[2] => .32
)
如何避免捕获百分比“%”符号(在$result[0]
中)?
答案 0 :(得分:6)
真的很简单。只需将你的正则表达式改为:
/^(?<int>[1-9][0-9]*|[0])(?<dec>\.[0-9]+)?/
(从匹配中删除\%?$
。)
如果你想确保%符号存在,但是不想捕获它(在这种情况下似乎无关紧要,但也许)你可以添加一个前瞻断言。 (?=...)
断言确保模式存在,但它不会改变匹配的内容。
/^(?<int>[1-9][0-9]*|[0])(?<dec>\.[0-9]+)?(?=%?$)/
答案 1 :(得分:1)
$result
数组的第一个元素将始终包含完整模式匹配(您不能告诉PHP不这样做,请参阅here),因此我们必须解决正则表达式本身的问题。在正则表达式中,您指定%
将 完整模式匹配 ,因为您明确告诉它可能出现在之前(以及内部)模式字符串($
符号)的结尾,您可以在此处\%?$
。
解决方案是在前瞻中指定%
(因此它不会进入模式字符串),并且由于%
是可选的,我们会在前瞻中查找{ {1}}或字符串结尾,因此%
永远不会进入完整模式匹配。
所以我添加了%
,告诉正则表达式提前查看(?=\%|$)
符号或字符串的结尾。
所以,以下正则表达式:
%
对于'0.32%'和'0.32'将输出:
preg_match('/^(?<int>[1-9][0-9]*|[0])(?<dec>\.[0-9]+)?(?=\%|$)/i', '0.32%', $result);
更新:我做了一些测试后更新了我的完整答案,所以请阅读上面的内容