最近在寫項目時,需要用到通配符匹配一些字符串,需要類似*匹配所有字符,?匹配單個字符的做法,在php中找到了fnmatch函數可使用,但發現它不能使用在windows的環境中,后來在網上搜索到一篇文章,地址如下:
http://bbs.phpchina.com/thread-80501-1-1.html
該貼中有兩種方法可以實現fnmatch函數,現貼如下:
function fnmatch($pattern, $string) //$pattern匹配式, $string被匹配的字符串{ $starStack = array(); //創建記錄pattern開始位置的棧,這個作用是像編輯器的后退 $sstrStack = array(); //創建記錄$string開始位置的棧 $countStack = 0; //棧大小,用一個同步記錄棧大小,減少count()時所耗的時間 $ptnStart = strlen($pattern) - 1; //定位匹配式最后一個字符, 算法是從字符串后面開始匹配 $strStart = strlen($string) - 1; //定位字符串的最好一個字符 for(; 0 <= $strStart; $strStart --) //開始匹配循環, 每匹配一個字符, $strStart就往前移一個字符 { $sc = $string{$strStart}; //取得當前在比較的字符 $pc = ($ptnStart < 0) ? '' : $pattern{$ptnStart};//取得匹配式當前的字符,已到結束位置,給個空 if($sc !== $pc) { //當兩個字符不相同時, 就要進行一些匹配式特殊字符的比較 if($pc === '*') //如果匹配式當前字符是*號, 進行*號匹配 { while($ptnStart > 0 && ($pc = $pattern{$ptnStart - 1}) === '*') $ptnStart --; //while這段是去除幾個連續的*號, 并嘗試和取得下一個字符 if($ptnStart > 0 && ($pc === $sc || $pc === '?'))//比較下個字符是否相同或是?號 { //如果下一個字符匹配成功 $starStack[$countStack] = $ptnStart;//保存這個*號的位置 $sstrStack[$countStack] = $strStart;//保存$string開始位置 $countStack ++; //棧向下移一 $ptnStart -= 2; //匹配式定位,前移兩位,分別是當前*號位和已經匹配的一個 continue; //進行下一次循環 } } elseif($pc === '?') //如果匹配式當前字符是?號, 進行?號匹配 { $ptnStart --; //?號匹配是字符串同步前移一個位置 } elseif($countStack > 0) //如果不是通配符,檢查棧中是否有保存上一個*號的位置 { //有就還原此*號位置, 回到上一個*號處再次進行匹配 $countStack --; $ptnStart = $starStack[$countStack];//還原*號位置 $strStart = $sstrStack[$countStack];//還原$string開始位置 } else { return false; //以上情況都沒有的話, 匹配失敗, 返回flase } } else { $ptnStart --; //字符串位置和匹配式位置上相同,前移一位,繼續下個匹配 } } //匹配循環結束 if($ptnStart === -1) //剛好匹配式的位置也結束, 則匹配成功, 返回true { return true; } elseif($ptnStart >= 0) //匹配式并沒有結束, 還有一些沒有匹配 { while($ptnStart > 0 && $pattern{$ptnStart} === '*')//檢查剩下的是不是都是*號,去除這些*號 $ptnStart --; if($pattern{$ptnStart} === '*') //最后的只有一個*號結束的話, 就匹配成功, 返回true return true; else return false; //否則, 返回false } return false;}
if (!function_exists('fnmatch')) { function fnmatch($pattern, $string) { return @preg_match('/^' . strtr(addcslashes($pattern, '/.+^$(){}=!<>|'), array('*' => '.*', '?' => '.?')) . '$/i', $string); } }
我愛中國
匹配 我愛??
就無法實現了,因為“中國”這個字符算4個字符,假如 匹配 我愛???? 應該就沒問題了,但是這樣對于我們來說使用非常的不方便,于是我改了一個第一個函數的實現,使用mb_strlen的方法來統計和分割字符,實現如下:
鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。
新聞熱點
疑難解答