соответствие строки 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

Author: dynamic, 2011-05-28

5 answers

Здесь нет необходимости в preg_match. В PHP есть функция сравнения подстановочных знаков, специально созданная для таких случаев:

fnmatch()

И fnmatch('dir/*/file', 'dir/folder1/file'), скорее всего, уже будут работать на вас. Но будьте осторожны, что подстановочный знак * также добавит дополнительные косые черты, как это сделал бы preg_match.

 38
Author: mario, 2011-05-28 18:30:20
.+?

Вызывает не жадное сопоставление для всех символов. Это НЕ равно "*", потому что оно не будет соответствовать пустой строке.

Следующий шаблон также будет соответствовать пустой строке:

.*?

Итак...

stringMatchWithWildcard ("hello", "hel*lo"); // will give true
 2
Author: vbence, 2011-05-28 17:07:50

Вы путаете окончание ($) и начало (^). Это:

preg_match( '/$' . $pattern . '^/i' , $source );

Должно быть:

preg_match( '/^' . $pattern . '$/i' , $source );
 2
Author: netcoder, 2011-05-28 17:12:43

Вместо этого вам следует просто использовать .*.

$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

 1
Author: Dogbert, 2011-05-28 17:12:01

Единственная проблема, с которой вы столкнетесь, заключается в том, что вызов preg_quote() будет экранирован символом звездочки. Учитывая это, ваш str_replace() заменит *, но не escape-символ перед ним.

Поэтому вам следует изменить str_replace('*' ..) на str_replace('\*'..)

 0
Author: Spudley, 2011-05-28 17:11:30