Reputation: 436
I need to specify a preferred optional sub pattern but allow for backup. Unfortunately both share part of a pattern, and the preferred match comes after. ex:
$string = "Fuzzy bunny is bald";
preg_match_all('@(?:bunny is (\w+)|(\w+) bunny)@',$string,$result);
The intended behavior is to ONLY match "bald", unless it cant, in which case it should match "Fuzzy" however because it first encounters a match with "Fuzzy" it does the reverse.
Thanks for your help.
Upvotes: 1
Views: 168
Reputation: 89584
You can try this:
$strings = array("Fuzzy bunny is bald", "Fuzzy bunny is");
$pattern = '~(?J)^(?(?=^[^b]*+bunny is \w++)^[^b]+bunny is (?<word>\w++)|(?<word>\w++) bunny)~';
foreach ($strings as $k => $string) {
if (preg_match($pattern, $string, $match))
echo "<br/>string$k : " . $match['word'] . "\n";
}
or this:
$pattern='~(?|(\w++) si ynnub|ynnub (\w++))~';
foreach ($strings as $k => $string) {
if (preg_match($pattern, strrev($string), $match))
echo "<br/>string$k : " . strrev($match[1]) . "\n";
}
Upvotes: 0
Reputation: 436
figured it out. Have to specify the capturing part of the non-preferring inside the preferred sub pattern, just without capturing it so it can see them at the same time. Then listing them in preferred order works. ex:
'@(?:\w+ bunny is (\w+)|(\w+) bunny)@'
Upvotes: 2