Reputation: 47
I'm trying to build a function that matches the math expression between two greater (or equal) or smaller (or equal) symbols.
I have the following preg_match function:
preg_match("/(<=?|>=?)(([0-9]|\+|\(|\))+)(<=?|>=?)/", "2<(2+2)<8", $matches);
When I read the $matches array I get:
Array
(
[0] => <(2+2)<
[1] => <
[2] => (2+2)
[3] => )
[4] => <
)
Can anyone explain why the closing ) gets matched as part of the (2+2) and on it's own? I would like it to only match the whole (2+2).
Upvotes: 0
Views: 72
Reputation:
Because you have a quantified capture group (...)+
Each pass through the capture group, resets the capture group to empty.
The result is you only see the last capture.
You can see it below as 3 start/end
.
( <=? | >=? ) # (1)
( # (2 start)
( # (3 start)
[0-9]
| \+
| \(
| \)
)+ # (3 end)
) # (2 end)
( <=? | >=? ) # (4)
The individual pieces are of no use in this case,
changing it to a cluster group will exclude it from the output array.
( <=? | >=? ) # (1)
( # (2 start)
(?:
[0-9]
| \+
| \(
| \)
)+
) # (2 end)
( <=? | >=? ) # (3)
Output
** Grp 0 - ( pos 0 , len 7 )
<(2+2)<
** Grp 1 - ( pos 0 , len 1 )
<
** Grp 2 - ( pos 1 , len 5 )
(2+2)
** Grp 3 - ( pos 6 , len 1 )
<
Upvotes: 0
Reputation: 9650
Because you've got two capturing groups for the expression between comparison signs:
(<=?|>=?)(([0-9]|\+|\(|\))+)(<=?|>=?)
^^ ^ ^
|`----- $3 -----' |
`------- $2 ------'
Change it to
(<=?|>=?)((?:[0-9]|\+|\(|\))+)(<=?|>=?)
^^
Upvotes: 1