There are two ways to implement the Fnmatch function in this paste, which is now affixed as follows:
function Fnmatch ($pattern, $string)//$pattern match, $string the matched string {$starStack = array (); Creates a stack that records the starting position of the pattern, which is like the editor's Back $sstrStack = Array (); Create a stack $countStack record $string start position = 0; Stack size, the time taken to reduce count () by a synchronous record stack size $ptnStart = strlen ($pattern)-1; Position the last character of the match, the algorithm starts from behind the string $strStart = strlen ($string)-1; The best one character for the position string for (; 0 <= $strStart; $strStart-)//Start match loop, each match one character, $strStart move forward one character {$sc = $strin g{$strStart}; Get the characters currently in the comparison $pc = ($ptnStart < 0)? ': $pattern {$ptnStart};//the current character of the match, to the end position, give an empty if ($SC!== $pc) {//When two characters When not the same, some matching special characters should be compared if ($pc = = = ' * ')//if the matching current character is an * number, the * number matches {while ($ptnStart > 0 && ($pc = $pattern {$ptnStart-1}) = = = ' * ') $ptnStart--; While this segment is to remove several consecutive * numbers and try and get the next character if ($ptnStart > 0 && ($pc = = = $SC | | $pc = = = '? ')) Compare whether the next character is the same or the {///if the next character matches successfully $starStack [$countStack] = $pt nstart;//Save the position of this * number $sstrStack [$countStack] = $strStart;//save $string start position $countStack + +; The stack moves down one $ptnStart-= 2; Matching positioning, forward two bits, respectively, is the current * number and a matching continue; Make the Next Loop}} elseif ($pc = = = '? ') If the current character of the match is the? number, match {$ptnStart-; The match number is a string that moves forward one position} elseif ($countStack > 0)//If it is not a wildcard, check the stack for the position where the previous * number was saved { To restore this position, go back to the previous * number again to match $countStack-; $ptnStart = $starStack [$countStack];//Restore * Number position $strStart = $sstrStack [$countStack];//restore $string start position } else {RETUrn false; If none of the above, match failed, return flase}} else {$ptnStart--; The string position and match position are the same, move forward one bit, continue next match}}//Match Loop End if ($ptnStart = = = 1) The position of the exact match is also ended, then the match succeeds, returning true {return true; } elseif ($ptnStart >= 0)//match did not end, and some did not match {while ($ptnStart > 0 && $patter n{$ptnStart} = = = ' * ')//check whether the remaining is the * number, remove these * number $ptnStart-; if ($pattern {$ptnStart} = = = ' * ')//Last only one * number ends, the match succeeds and returns true return true; else return false; Otherwise, return false} return false;}
if (!function_exists (' Fnmatch ')) { function Fnmatch ($pattern, $string) { return @preg_match ('/^ '. STRTR ( Addcslashes ($pattern, '. +^$ () {}=!<>| '), Array (' * ' + '. * ', '? ' = ') '.? ') . ' $/i ', $string); } }
Both of these methods can be implemented, but because I want to match the Chinese, such as
I love China
Match my love??
Can not be achieved, because "China" this character is counted 4 characters, if match I love???? Should be no problem, but this is very inconvenient for us to use, so I changed the implementation of the first function, using the Mb_strlen method to statistics and segmentation of characters, the implementation of the following:
function Fnmatch ($pattern, $string)//$pattern match, $string the matched string {$encoding = gb2312;//to define the encoding based on the encoding of its own page $star Stack = Array (); Creates a stack that records the starting position of the pattern, which is like the editor's Back $sstrStack = Array (); Create a stack $countStack record $string start position = 0; Stack size, the time taken to reduce count () by a synchronous record stack size $ptnStart = Mb_strlen ($pattern, $encoding)-1; Position the last character of the match, the algorithm starts from the string after the match $strStart = Mb_strlen ($string, $encoding)-1; The best one character for the position string for (; 0 <= $strStart; $strStart-)//Start match loop, each match one character, $strStart move forward one character {$sc = Mb_substr ($str ING, $strStart, 1, $encoding); Gets the character currently in the comparison $pc = ($ptnStart < 0)? ": Mb_substr ($pattern, $ptnStart, 1, $encoding);//Gets the matching current character, to the end position, to an empty if ($SC!== $pc) { When two characters are not the same, some matching special characters will be compared if ($pc = = = ' * ')//if the current character of the match is the * number, the * number is matched {while ($ptnStart > 0 && ($pc = Mb_substr ($pattern, $PtnStart-1, 1, $encoding)) = = = ' * ') $ptnStart--; While this segment is to remove several consecutive * numbers and try and get the next character if ($ptnStart > 0 && ($pc = = = $SC | | $pc = = = '? ')) Compare whether the next character is the same or the {///if the next character matches successfully $starStack [$countStack] = $pt nstart;//Save the position of this * number $sstrStack [$countStack] = $strStart;//save $string start position $countStack + +; The stack moves down one $ptnStart-= 2; Matching positioning, forward two bits, respectively, is the current * number and a matching continue; Make the Next Loop}} elseif ($pc = = = '? ') If the current character of the match is the? number, match {$ptnStart-; The match number is a string that moves forward one position} elseif ($countStack > 0)//If it is not a wildcard, check the stack for the position where the previous * number was saved { To restore this position, go back to the previous * number again to match $countStack-; $ptnStart = $starStack [$countStack];//restore * Number position $strStart = $sstrStack [$countStack];//restore $string start position} else {R Eturn false; If none of the above, match failed, return flase}} else {$ptnStart--; The string position and match position are the same, move forward one bit, continue next match}}//Match Loop End if ($ptnStart = = = 1) The position of the exact match is also ended, then the match succeeds, returning true {return true; } elseif ($ptnStart >= 0)//match did not end, and some did not match {while ($ptnStart > 0 && mb_subs TR ($pattern, $ptnStart, 1, $encoding) = = = = ' * ')//check whether the remainder is the * number, remove these * number $ptnStart-; if (Mb_substr ($pattern, $ptnStart, 1, $encoding) = = = "*")//Last only one * number ends, the match succeeds, returns true return true; else return false; Otherwise, return false} return false;}
The implementation is complete, can perfectly match Chinese.
http://www.bkjia.com/PHPjc/621633.html www.bkjia.com true http://www.bkjia.com/PHPjc/621633.html techarticle There are two ways to implement the Fnmatch function, now affixed as follows: function Fnmatch ($pattern, $string)//$pattern match, $string the matched string {$starStack = Array ( ); Create a ...