preg_match matching pattern with asterisk (*) in it [duplicate]
preg_match('/te**ed/i', 'tested', $matches);
gives me the following error:
ERROR: nothing to repeat at offset 3
What do I do to allow the pattern to actually contain 开发者_开发问答*
?
To use literal asterisks you have to escape them with backslashes. To match the literal te**ed
you would use an expression like this:
preg_match('/te\*\*ed/i', 'tested', $matches); // no match (te**ed != tested)
But I doubt this is what you wanted. If you mean, match any character, you need to use .
:
preg_match('/te..ed/is', 'tested', $matches); // match
If you really want any two lower case letter, then this expression:
preg_match('/te[a-z]{2}ed/i', 'tested', $matches); // match
Putting a backslash before any character wil tell PHP that the character should be taken as is, not as a special regex character. So:
preg_match('/te\\**ed/i', 'tested', $matches);
If you want to use asterisk-like search, you can use next function:
function match_string($pattern, $str)
{
$pattern = preg_replace('/([^*])/e', 'preg_quote("$1", "/")', $pattern);
$pattern = str_replace('*', '.*', $pattern);
return (bool) preg_match('/^' . $pattern . '$/i', $str);
}
Example:
match_string("*world*","hello world") // returns true
match_string("world*","hello world") // returns false
match_string("*world","hello world") // returns true
match_string("world*","hello world") // returns false
match_string("*ello*w*","hello world") // returns true
match_string("*w*o*r*l*d*","hello world") // returns true
Improving upon Viktor Kruglikov's answer, this is the PHP 7.3 way of doing such a thing:
private function match(string $pattern, string $target): bool
{
$pattern = preg_replace_callback('/([^*])/', function($m) {return preg_quote($m[0], '/');}, $pattern);
$pattern = str_replace('*', '.*', $pattern);
return (bool) preg_match('/^' . $pattern . '$/i', $target);
}
精彩评论