Reputation: 111829
I'm looking inside string 3-431 a4-2 4-13
and want to find 3-431
, a4-2
and 4-13
. I use the following pattern:
/(.*-.* )*/gU
and I get the desired result without a problem: Online demo
The question is - how to achieve same result when I want to look inside string that start and ends with some other substrings for example [
and ]
.
If I modify subject to [3-431 a4-2 4-13 ]
and regex to /\[(.*-.* )*\]/gU
I'm getting only the last occurence: 4-13
and I'm not getting same results as in 1st example. Online demo
Why is that and how can I fix this?
Upvotes: 0
Views: 42
Reputation: 30995
You don't need to use a regex you can use explode
or split by space:
$str = "3-431 a4-2 4-13";
$parts = explode(" ", $str);
echo $parts [0]; // 3-431
echo $parts [1]; // a4-2
echo $parts [2]; // 4-13
However, if you still want to use a regex, then you can use:
$re = "/(\\w+-\\w+)/";
$str = "3-431 a4-2 4-13";
preg_match_all($re, $str, $matches);
Btw, if your string is always separated by spaces, then you can also use this regex:
$re = "/(\\S+)/";
$str = "3-431 a4-2 4-13";
preg_match_all($re, $str, $matches);
On the other hand, if your string starts and ends with [
and ]
, as [3-431 a4-2 4-13 ]
. The idea is to leverage the discard technique, you could use this regex:
[[\]](*SKIP)(*FAIL)|(\S+)
And also, getting the same result using preg_split
for above string:
$exploded = preg_split('[[\]\s]+', '[3-431 a4-2 4-13]', NULL, PREG_SPLIT_NO_EMPTY)
Upvotes: 1
Reputation: 6173
If you still wanted to do regex this will work:
(^|\])[^[]*\[([^[]*-[^[]* )*(*SKIP)(*FAIL)|(.*-.* )+
Basically, if the occurrence happens outside of [
and ]
it will fail.
The reason that your were only getting one match is that the global modifier will only match another occurrence after the first match ends, which in your case was after the closing brace.
Upvotes: 0
Reputation: 1048
First of all, you should use .+
and not .*
since +
means at least once. Then your regex is:
/\[(\w+-\w+)*\s*\]/sgU
Upvotes: 0