соответствие строки php с подстановочным знаком *? - PullRequest
28 голосов
/ 28 мая 2011

Я хочу дать возможность сопоставить строку с подстановочным знаком *.

Пример

$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

Ответы [ 6 ]

45 голосов
/ 28 мая 2011

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

fnmatch()

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

2 голосов
/ 28 мая 2011

Вы смешиваете окончание ($) и начало (^).Это:

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

Должно быть:

preg_match( '/^' . $pattern . '$/i' , $source );
2 голосов
/ 28 мая 2011
.+?

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

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

.*?

, так что ...

stringMatchWithWildcard ("hello", "hel*lo"); // will give true
2 голосов
/ 28 мая 2011

Вы должны просто использовать .* вместо.

$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

0 голосов
/ 25 февраля 2019
$pattern = str_replace( '\*' , '.+?', $pattern);   // at least one character
0 голосов
/ 28 мая 2011

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

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

...