Php search string (with wildcards)
This is one of the few cases where regular expressions are actually helpful. :)
if (preg_match('/my (\w+) has/', $str, $matches)) {
echo $matches[1];
}
See the documentation for preg_match.
wildcard pattern could be converted to regex pattern like this
function wildcard_match($pattern, $subject) {
$pattern = strtr($pattern, array(
'*' => '.*?', // 0 or more (lazy) - asterisk (*)
'?' => '.', // 1 character - question mark (?)
));
return preg_match("/$pattern/", $subject);
}
if string contents special characters, e.g. \.+*?^$|{}/'#, they should be \-escaped
don't tested:
function wildcard_match($pattern, $subject) {
// quotemeta function has most similar behavior,
// it escapes \.+*?^$[](), but doesn't escape |{}/'#
// we don't include * and ?
$special_chars = "\.+^$[]()|{}/'#";
$special_chars = str_split($special_chars);
$escape = array();
foreach ($special_chars as $char) $escape[$char] = "\\$char";
$pattern = strtr($pattern, $escape);
$pattern = strtr($pattern, array(
'*' => '.*?', // 0 or more (lazy) - asterisk (*)
'?' => '.', // 1 character - question mark (?)
));
return preg_match("/$pattern/", $subject);
}
I agree that regex are much more flexible than wildcards, but sometimes all you want is a simple way to define patterns. For people looking for a portable solution (not *NIX only) here is my implementation of the function:
function wild_compare($wild, $string) {
$wild_i = 0;
$string_i = 0;
$wild_len = strlen($wild);
$string_len = strlen($string);
while ($string_i < $string_len && $wild[$wild_i] != '*') {
if (($wild[$wild_i] != $string[$string_i]) && ($wild[$wild_i] != '?')) {
return 0;
}
$wild_i++;
$string_i++;
}
$mp = 0;
$cp = 0;
while ($string_i < $string_len) {
if ($wild[$wild_i] == '*') {
if (++$wild_i == $wild_len) {
return 1;
}
$mp = $wild_i;
$cp = $string_i + 1;
}
else
if (($wild[$wild_i] == $string[$string_i]) || ($wild[$wild_i] == '?')) {
$wild_i++;
$string_i++;
}
else {
$wild_i = $mp;
$string_i = $cp++;
}
}
while ($wild[$wild_i] == '*') {
$wild_i++;
}
return $wild_i == $wild_len ? 1 : 0;
}
Naturally the PHP implementation is slower than fnmatch(), but it would work on any platform.
It can be used like this:
if (wild_compare('regex are * useful', 'regex are always useful') == 1) {
echo "I'm glad we agree on this";
}