соответствие строки php подстановочному знаку *?
Я хочу предоставить возможность сопоставлять строку с подстановочным знаком *
.
Пример
$mystring = 'dir/folder1/file';
$pattern = 'dir/*/file';
stringMatchWithWildcard($mystring,$pattern); //> Returns true
Пример 2:
$mystring = 'string bl#abla;y';
$pattern = 'string*y';
stringMatchWithWildcard($mystring,$pattern); //> Returns true
Я подумал что-то вроде:
function stringMatch($source,$pattern) {
$pattern = preg_quote($pattern,'/');
$pattern = str_replace( '\*' , '.*?', $pattern); //> This is the important replace
return (bool)preg_match( '/^' . $pattern . '$/i' , $source );
}
В основном заменяя *
на .*?
(учитывая, что в среде *nix
*
соответствует empty
строка) ©vbence
Какие-либо улучшения/предложения?
//Добавлено return (bool)
, потому что preg_match возвращает int
5 answers
Здесь нет необходимости в preg_match
. В PHP есть функция сравнения подстановочных знаков, специально созданная для таких случаев:
И fnmatch('dir/*/file', 'dir/folder1/file')
, скорее всего, уже будут работать на вас. Но будьте осторожны, что подстановочный знак *
также добавит дополнительные косые черты, как это сделал бы preg_match.
.+?
Вызывает не жадное сопоставление для всех символов. Это НЕ равно "*", потому что оно не будет соответствовать пустой строке.
Следующий шаблон также будет соответствовать пустой строке:
.*?
Итак...
stringMatchWithWildcard ("hello", "hel*lo"); // will give true
Вы путаете окончание ($
) и начало (^
). Это:
preg_match( '/$' . $pattern . '^/i' , $source );
Должно быть:
preg_match( '/^' . $pattern . '$/i' , $source );
Вместо этого вам следует просто использовать .*
.
$pattern = str_replace( '*' , '.*', $pattern); //> This is the important replace
Редактировать: Также ваши ^
и $
были в неправильном порядке.
<?php
function stringMatchWithWildcard($source,$pattern) {
$pattern = preg_quote($pattern,'/');
$pattern = str_replace( '\*' , '.*', $pattern);
return preg_match( '/^' . $pattern . '$/i' , $source );
}
$mystring = 'dir/folder1/file';
$pattern = 'dir/*/file';
echo stringMatchWithWildcard($mystring,$pattern);
$mystring = 'string bl#abla;y';
$pattern = 'string*y';
echo stringMatchWithWildcard($mystring,$pattern);
Рабочая демонстрация: http://www.ideone.com/mGqp2
Единственная проблема, с которой вы столкнетесь, заключается в том, что вызов preg_quote()
будет экранирован символом звездочки. Учитывая это, ваш str_replace()
заменит *
, но не escape-символ перед ним.
Поэтому вам следует изменить str_replace('*' ..)
на str_replace('\*'..)