Соответствие 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
Ответы
Ответ 1
Здесь нет необходимости preg_match
. PHP имеет функцию сравнения символов, специально предназначенную для таких случаев:
fnmatch()
И fnmatch('dir/*/file', 'dir/folder1/file')
скорее всего уже сработает для вас. Но будьте осторожны, что подстановочный знак *
также добавил бы дополнительные косые черты, например preg_match.
Ответ 2
.+?
Вызывает нежелательное соответствие для всех символов. Это НЕ равно "*", потому что он не будет соответствовать пустой строке.
Следующий шаблон также будет соответствовать пустой строке:
.*?
так...
stringMatchWithWildcard ("hello", "hel*lo"); // will give true
Ответ 3
Вы смешиваете финал ($
) и начинаете (^
). Это:
preg_match( '/$' . $pattern . '^/i' , $source );
Должно быть:
preg_match( '/^' . $pattern . '$/i' , $source );
Ответ 4
Единственная проблема, с которой вы столкнетесь, состоит в том, что вызов preg_quote()
будет вызывать символ звездочки. Учитывая, что ваш str_replace()
заменит *
, но не символ escape перед ним.
Поэтому вы должны изменить str_replace('*' ..)
на str_replace('\*'..)
Ответ 5
Вместо этого следует использовать .*
.
$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