php適用於windows的fnmatch(匹配函數),可匹配中文。_PHP教程

來源:互聯網
上載者:User
該貼中有兩種方法可以實現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的方法來統計和分割字元,實現如下:

function fnmatch($pattern, $string)         //$pattern匹配式, $string被匹配的字串{$encoding = gb2312;//根據自己的頁面的編碼,來定義這個編碼    $starStack = array();                   //建立記錄pattern開始位置的棧,這個作用是像編輯器的後退    $sstrStack = array();                   //建立記錄$string開始位置的棧    $countStack = 0;                        //棧大小,用一個同步記錄棧大小,減少count()時所耗的時間    $ptnStart = mb_strlen($pattern, $encoding) - 1;       //定位匹配式最後一個字元, 演算法是從字串後面開始匹配    $strStart = mb_strlen($string, $encoding) - 1;        //定位字串的最好一個字元    for(; 0 <= $strStart; $strStart --)     //開始匹配迴圈, 每匹配一個字元, $strStart就往前移一個字元    {$sc = mb_substr($string, $strStart, 1, $encoding);           //取得當前在比較的字元$pc = ($ptnStart < 0) ? '' : mb_substr($pattern, $ptnStart, 1, $encoding);//取得匹配式當前的字元,已到結束位置,給個空        if($sc !== $pc)        {                                   //當兩個字元不相同時, 就要進行一些匹配式特殊字元的比較            if($pc === '*')                 //如果匹配式當前字元是*號, 進行*號匹配            {                while($ptnStart > 0 && ($pc = mb_substr($pattern, $ptnStart-1, 1, $encoding)) === '*')                    $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 && mb_substr($pattern, $ptnStart, 1, $encoding) === '*')//檢查剩下的是不是都是*號,去除這些*號            $ptnStart --;        if(mb_substr($pattern, $ptnStart, 1, $encoding) === '*')     //最後的只有一個*號結束的話, 就匹配成功, 返回true            return true;        else            return false;                   //否則, 返回false    }    return false;}

實現完畢,可完美匹配中文了。

http://www.bkjia.com/PHPjc/621633.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/621633.htmlTechArticle該貼中有兩種方法可以實現fnmatch函數,現貼如下: function fnmatch($pattern, $string) //$pattern匹配式, $string被匹配的字串{ $starStack = array(); //創...

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.