Chris.Caldwell
Chris.Caldwell

Reputation: 436

specify preferential subpattern in regex

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

Answers (2)

Casimir et Hippolyte
Casimir et Hippolyte

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

Chris.Caldwell
Chris.Caldwell

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

Related Questions