2011-05-28 163 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);