Reputation: 313
Let's take an example of following string:
$string = "length:max(260):min(20)";
In the above string, :max(260):min(20)
is optional. I want to get it if it is present otherwise only length
should be returned.
I have following regex but it doesn't work:
/(.*?)(?::(.*?))?/se
It doesn't return anything in the array when I use preg_match
function.
Remember, there can be something else than above string. Maybe like this:
$string = "number:disallow(negative)";
Is there any problem in my regex or PHP won't return anything? Dumping preg_match
returns int 1
which means the string matches the regex.
Fully Dumped:
int 1
array (size=2)
0 => string '' (length=0)
1 => string '' (length=0)
Upvotes: 0
Views: 410
Reputation: 13669
I tried to prepare a regex which can probably solve your issue and also add some value to it
this regex will not only match the optional elements but will also capture in key value pair
Regex
/(?<=:|)(?'prop'\w+)(?:\((?'val'.+?)\))?/g
Test string
length:max(260):min(20)
length
number:disallow(negative)
Result
length
max
260
min
20
length
number
disallow
negative
try demo here
EDIT
I think I understand what you meant by duplicate array with different key, it was due to named captures eg. prop & val
here is the revision without named capturing
Regex
/(?<=:|)(\w+)(?:\((.+?)\))?/
Sample code
$str = "length:max(260):min(20)";
$str .= "\nlength";
$str .= "\nnumber:disallow(negative)";
preg_match_all("/(?<=:|)(\w+)(?:\((.+?)\))?/",
$str,
$matches);
print_r($matches);
Result
Array
(
[0] => Array
(
[0] => length
[1] => max(260)
[2] => min(20)
[3] => length
[4] => number
[5] => disallow(negative)
)
[1] => Array
(
[0] => length
[1] => max
[2] => min
[3] => length
[4] => number
[5] => disallow
)
[2] => Array
(
[0] =>
[1] => 260
[2] => 20
[3] =>
[4] =>
[5] => negative
)
)
try demo here
Upvotes: 1
Reputation: 48711
You're using single character (.
) matching in the case of being lazy, at the very beginning. So it stops at the zero position. If you change your preg_match
function to preg_match_all
you'll see the captured groups.
Another problem is with your Regular Expression. You're killing the engine. Also e
modifier is deprecated many many decades before!!! and yet it was used in preg_replace
function only.
Don't use s
modifier too! That's not needed.
This works at your case:
/([^:]+)(:.*)?/
Upvotes: 3