[英]PHP not respecting non-capturing group with lookahead with a capturing group inside
我有这个PHP正则表达式匹配项:
preg_match_all('/(\d+)(?:\.(?=(\d+)))?/', "43.3", $matches, PREG_SET_ORDER);
(至少在我看来)意味着:
Match one or more numbers as a group, and if there is a '.' after that
group followed by a group of numbers, match those too, but ignore the '.'.
因此,可能的字符串为:
1
23244
24.5
2.454646
但不是:
1.
现在,它可以在regex101.com
与我抛出的任何测试字符串完美配合,但似乎不适用于PHP。 这是我得到var_dump($matches)
:
array(2) {
[0]=>
array(3) {
[0]=>
string(3) "43."
[1]=>
string(2) "43"
[2]=>
string(1) "3"
}
[1]=>
array(2) {
[0]=>
string(1) "3"
[1]=>
string(1) "3"
}
}
43
之后我明白了? 3
? 第一个匹配始终是完整匹配,就好像您的整个模式都用括号括起来一样。 我认为您无法关闭此功能。
由于第一组中有两个(\\d+)
,因此第一组中得到3
。 如果不需要,请从?=
之后的括号中删除括号。
如果您只需要完整的数字,可以尝试如下操作:
>>> preg_match_all('/(?<!\d)\d+(?:\.\d+)?(?![\d.])/', "43.3 31.52 1.", $matches);
=> 2
>>> $matches
=> [
[
"43.3",
"31.52"
]
]
如果只有一个数字,则应使用preg_match
,而不是preg_match_all
。 例如
>>> preg_match_all('/(\d+)(?:\.(\d+))?/', "43.3", $matches)
=> 1
>>> $matches
=> [
[
"43.3"
],
[
"43"
],
[
"3"
]
]
您始终可以将array_shift
移出完整匹配。
两个子数组的[0]
部分中的值是在每种情况下都匹配的整个字符串,然后[1]
和[2]
用于捕获组。
总的来说有两个匹配项,并且第一个匹配项的全文为43.
这是因为您的正则表达式说:
(\\d+)
(?:\\.(?=(\\d+)))?
字符串的43.
部分满足该要求,就像在点的末尾是点3
。
这个问题尚不十分清楚,但听起来您根本根本不想使用先行(?=…)
。
例如,/( /(\\d+)(?:\\.(\\d+))?/
: /(\\d+)(?:\\.(\\d+))?/
将给出以下内容:
// For "43.3"
array(3) {
[0]=>
string(4) "43.3" // whole match
[1]=>
string(2) "43" // first capturing group
[2]=>
string(1) "3" // second capturing group
}
// For "1."
array(2) {
[0]=>
string(1) "1"
[1]=>
string(1) "1"
}
// For "12345"
array(2) {
[0]=>
string(5) "12345"
[1]=>
string(5) "12345"
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.