Reputation: 6362
I have this string to test and can't manage to make it works as I want :
<?php
$string = '500 or fatal error ?';
$regex = '#(fatal|500)#';
if (preg_match($regex, $string, $return)) {
// Return 500
echo $return[1];
}
?>
I want my script to return fatal instead of 500 because it's my first selector. Is it possible ?
Thanks by advance, and sorry for my poor english.
P.S. : Maybe my title isn't really clear, but I don't know how to explain it better. If you find it, change it.
Upvotes: 3
Views: 451
Reputation: 32807
There are two kinds of regular expression engines: text-directed engines
, and regex-directed
engines.
php is regex-directed
engine which would always return the leftmost match, even if "500" match could be found later
The engine will start at the first character of the string. It will try all possible permutations of the regular expression at the first character. Only if all possibilities have been tried and found to fail, will the engine continue with the second character in the text. Again, it will try all possible permutations of the regex, in exactly the same order. The result is that the regex-directed engine will return the leftmost match.
You can find more info here
Upvotes: 2
Reputation: 59709
If you want to do it with only one regex, you can do it like this:
$selectors = array( 'fatal', '500'); // Array of selectors (in priority order)
$delimiter = '/';
$regex = $delimiter . '(' . implode('|', array_map( 'preg_quote', $selectors, array_fill( 0, count( $selectors), '/'))) . ')' . $delimiter;
preg_match_all( $regex, $string, $matches);
See which of the selectors we found, in order of the array:
$found_selectors = array_flip( $matches[1]);
foreach( $selectors as $selector) {
if( isset( $found_selectors[$selector]))
return $selector;
}
Note that I flipped the $matches[1]
array to get constant lookup time into the array, instead of doing an array_search()
/ in_array()
which will both do a linear search.
You can see from this demo that this produces fatal
, given your input string.
Upvotes: 2
Reputation: 19257
it's not possible as you are envisioning, but a different implementation will make it work
$string = '500 or fatal error';
$regexes = array('#\bfatal\b#', '#\b500\b#');
$match = null;
foreach ($regexes as $re)
if (preg_match($re, $string, $match))
break;
# $match is null -> not found
Upvotes: 2