2011-05-28 164 views
23

我想给字符串与通配符*匹配的可能性。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

回答

35

没有必要preg_match这里。PHP有一个通配符比较功能,专门针对这种情况提出:

fnmatch()

而且fnmatch('dir/*/file', 'dir/folder1/file')很可能已经为你工作。但要注意,*通配符同样会增加更多的斜线,比如preg_match。

+0

嗨马里奥。 fnmatches还有一些其他功能,如'[]'。我只需要'*'作为“特殊字符” – dynamic 2011-05-29 16:11:36

+2

fnmatch在非POSIX系统上不受支持。 (我发现php5.3 +现在也支持windows)。所以这并不总是最好的方法 – Pinoniq 2014-05-21 14:49:58

0

你就会有一个问题是,调用preg_quote()将难逃星号字符。鉴于此,您的str_replace()将取代*,但不是其前面的转义字符。

因此,你应该改变str_replace('*' ..)str_replace('\*'..)

+0

我错过了从documetnatnion我的坏。固定 – dynamic 2011-05-28 17:14:14

1

你应该只使用.*代替。

$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

我不知道如果我想给匹配这个''目录//文件'与''目录/ * /文件''的可能性'' – dynamic 2011-05-28 17:08:39

+0

'。*'是贪婪的,它会吃掉所有剩下的你的字符串,不只是最少数量的字符来继续这些模式。所以如果你在'。*'后面有任何东西,结果总是假的。 – vbence 2011-05-28 17:09:33

+0

我认为这正是你想用你的描述中的'。+?'所做的。 – Dogbert 2011-05-28 17:10:13

2
.+? 

导致非贪婪匹配的所有字符。这不等于“*”,因为它不会匹配空字符串。

以下模式将空字符串匹配太:

.*? 

所以......

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

你认为我应该允许空串吗?也考虑一下dir:''dir // file''是否匹配''dir/*/file''? – dynamic 2011-05-28 17:11:02

+0

如果您希望它与OS shell的工作方式类似,那么您必须允许空字符串。只需在窗口中使用'echo> hello',然后在窗口中使用'dir hello *',或者在* nix中使用'ls hello *'。在这个上下文中*匹配空字符串。 – vbence 2011-05-28 17:14:23

+0

对你的-1进行评论会很礼貌。 – vbence 2011-05-28 17:16:48

2

你混在一起结束($),并开始(^)。这:

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

应该是:

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