php string matching with wildcard *?

2019-03-17 06:50发布

问题:

I want to give the possibility to match string with wildcard *.

Example

$mystring = 'dir/folder1/file';
$pattern = 'dir/*/file';

stringMatchWithWildcard($mystring,$pattern);  //> Returns true

Example 2:

$mystring = 'string bl#abla;y';
$pattern = 'string*y'; 

stringMatchWithWildcard($mystring,$pattern);  //> Returns true

I thought something like:

function stringMatch($source,$pattern) {
    $pattern = preg_quote($pattern,'/');        
    $pattern = str_replace( '\*' , '.*?', $pattern);   //> This is the important replace
    return (bool)preg_match( '/^' . $pattern . '$/i' , $source );
}

Basically replacing * to .*? (considering in *nix environment * matches empty string) ©vbence

Any improvments/suggests?

// Added return (bool) because preg_match returns int

回答1:

There is no need for preg_match here. PHP has a wildcard comparison function, specifically made for such cases:

fnmatch()

And fnmatch('dir/*/file', 'dir/folder1/file') would likely already work for you. But beware that the * wildcard would likewise add further slashes, like preg_match would.



回答2:

.+?

Causes non-greedy matching for all characters. This is NOT equal to "*" becuase it will not match the empty string.

The following pattern will match the empty string too:

.*?

so...

stringMatchWithWildcard ("hello", "hel*lo"); // will give true


回答3:

You should just use .* instead.

$pattern = str_replace( '*' , '.*', $pattern);   //> This is the important replace

Edit: Also your ^ and $ were in the wrong order.

<?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); 

Working demo: http://www.ideone.com/mGqp2



回答4:

You're mixing up ending ($) and beginning (^). This:

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

Should be:

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


回答5:

The one problem you'll have is that the call to preg_quote() will escape the asterisk character. Given that, your str_replace() will replace the *, but not the escape character in front of it.

Therefore you should change the str_replace('*' ..) with str_replace('\*'..)



回答6:

$pattern = str_replace( '\*' , '.+?', $pattern);   // at least one character