热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

php适用于windows的fnmatch(匹配函数),可匹配中文。_PHP教程

php适用于windows的fnmatch(匹配函数),可匹配中文。。该贴中有两种方法可以实现fnmatch函数,现贴如下:functionfnmatch($pattern,$string)$pattern匹配式,$string被匹配的字符串{$starStackarray();创
该贴中有两种方法可以实现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) ? &#39;&#39; : $pattern{$ptnStart};//取得匹配式当前的字符,已到结束位置,给个空
        if($sc !== $pc)
        {                                   //当两个字符不相同时, 就要进行一些匹配式特殊字符的比较
            if($pc === &#39;*&#39;)                 //如果匹配式当前字符是*号, 进行*号匹配
            {
                while($ptnStart > 0 && ($pc = $pattern{$ptnStart - 1}) === &#39;*&#39;)
                    $ptnStart --;           //while这段是去除几个连续的*号, 并尝试和取得下一个字符
                if($ptnStart > 0 && ($pc === $sc || $pc === &#39;?&#39;))//比较下个字符是否相同或是?号
                {                           //如果下一个字符匹配成功
                    $starStack[$countStack] = $ptnStart;//保存这个*号的位置
                    $sstrStack[$countStack] = $strStart;//保存$string开始位置
                    $countStack ++;         //栈向下移一
                    $ptnStart -= 2;         //匹配式定位,前移两位,分别是当前*号位和已经匹配的一个
                    continue;               //进行下一次循环
                }
            }
            elseif($pc === &#39;?&#39;)             //如果匹配式当前字符是?号, 进行?号匹配
            {
                $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} === &#39;*&#39;)//检查剩下的是不是都是*号,去除这些*号
            $ptnStart --;
        if($pattern{$ptnStart} === &#39;*&#39;)     //最后的只有一个*号结束的话, 就匹配成功, 返回true
            return true;
        else
            return false;                   //否则, 返回false
    }
    return false;
}

if (!function_exists(&#39;fnmatch&#39;)) {
        function fnmatch($pattern, $string) {
            return @preg_match(&#39;/^&#39; . strtr(addcslashes($pattern, &#39;.+^$(){}=!<>|&#39;), array(&#39;*&#39; => &#39;.*&#39;, &#39;?&#39; => &#39;.?&#39;)) . &#39;$/i&#39;, $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) ? &#39;&#39; : mb_substr($pattern, $ptnStart, 1, $encoding);//取得匹配式当前的字符,已到结束位置,给个空
        if($sc !== $pc)
        {                                   //当两个字符不相同时, 就要进行一些匹配式特殊字符的比较
            if($pc === &#39;*&#39;)                 //如果匹配式当前字符是*号, 进行*号匹配
            {
                while($ptnStart > 0 && ($pc = mb_substr($pattern, $ptnStart-1, 1, $encoding)) === &#39;*&#39;)
                    $ptnStart --;           //while这段是去除几个连续的*号, 并尝试和取得下一个字符
                if($ptnStart > 0 && ($pc === $sc || $pc === &#39;?&#39;))//比较下个字符是否相同或是?号
                {                           //如果下一个字符匹配成功
                    $starStack[$countStack] = $ptnStart;//保存这个*号的位置
                    $sstrStack[$countStack] = $strStart;//保存$string开始位置
                    $countStack ++;         //栈向下移一
                    $ptnStart -= 2;         //匹配式定位,前移两位,分别是当前*号位和已经匹配的一个
                    continue;               //进行下一次循环
                }
            }
            elseif($pc === &#39;?&#39;)             //如果匹配式当前字符是?号, 进行?号匹配
            {
                $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) === &#39;*&#39;)//检查剩下的是不是都是*号,去除这些*号
            $ptnStart --;
        if(mb_substr($pattern, $ptnStart, 1, $encoding) === &#39;*&#39;)     //最后的只有一个*号结束的话, 就匹配成功, 返回true
            return true;
        else
            return false;                   //否则, 返回false
    }
    return false;
}

实现完毕,可完美匹配中文了。

www.bkjia.comtruehttp://www.bkjia.com/PHPjc/621633.htmlTechArticle该贴中有两种方法可以实现fnmatch函数,现贴如下: function fnmatch($pattern, $string) //$pattern匹配式, $string被匹配的字符串{ $starStack = array(); //创...


推荐阅读
  • 本文提供了一个详尽的前端开发资源列表,涵盖了从基础入门到高级应用的各个方面,包括HTML5、CSS3、JavaScript框架及库、移动开发、API接口、工具与插件等。 ... [详细]
  • 本文介绍了用户界面(User Interface, UI)的基本概念,以及在iOS应用程序中UIView及其子类的重要性和使用方式。文章详细探讨了UIView如何作为用户交互的核心组件,以及它与其他UI控件和业务逻辑的关系。 ... [详细]
  • 本文探讨了线性表中元素的删除方法,包括顺序表和链表的不同实现策略,以及这些策略在实际应用中的性能分析。 ... [详细]
  • 本文介绍了使用Python和C语言编写程序来计算一个给定数值的平方根的方法。通过迭代算法,我们能够精确地得到所需的结果。 ... [详细]
  • 本文提供了一个关于AC自动机(Aho-Corasick Algorithm)的详细解析与实现方法,特别针对P3796题目进行了深入探讨。文章不仅涵盖了AC自动机的基本概念,还重点讲解了如何通过构建失败指针(fail pointer)来提高字符串匹配效率。 ... [详细]
  • 默认情况下,Git 使用 Nano 编辑器进行提交信息的编辑,但如果您更喜欢使用 Vim,可以通过简单的配置更改来实现这一变化。本文将指导您如何通过修改全局配置文件来设置 Vim 作为默认的 Git 提交编辑器。 ... [详细]
  • 在Notepad++中配置Markdown语法高亮及实时预览功能
    本文详细介绍了如何在Notepad++中配置Markdown语法高亮和实时预览功能,包括必要的插件安装和设置步骤。 ... [详细]
  • 如何寻找程序员的兼职机会
    随着远程工作的兴起,越来越多的程序员开始寻找灵活的兼职工作机会。本文将介绍几个适合程序员、设计师、翻译等专业人士的在线平台,帮助他们找到合适的兼职项目。 ... [详细]
  • Python网络编程:深入探讨TCP粘包问题及解决方案
    本文详细探讨了TCP协议下的粘包现象及其产生的原因,并提供了通过自定义报头解决粘包问题的具体实现方案。同时,对比了TCP与UDP协议在数据传输上的不同特性。 ... [详细]
  • 汇编语言标识符和表达式(四)(表达式与符号定义语句)
    7、表达式表达式是程序设计课程里的一个重要的基本概念,它可由运算符、操作符、括号、常量和一些符号连在一起的式子。在汇编语言中,表达式分为:数值表达式和地址表达式。(1)进制伪指令R ... [详细]
  • 本文分享了作者在使用LaTeX过程中的几点心得,涵盖了从文档编辑、代码高亮、图形绘制到3D模型展示等多个方面的内容。适合希望深入了解LaTeX高级功能的用户。 ... [详细]
  • LeetCode 102 - 二叉树层次遍历详解
    本文详细解析了LeetCode第102题——二叉树的层次遍历问题,提供了C++语言的实现代码,并对算法的核心思想和具体步骤进行了深入讲解。 ... [详细]
  • JavaScript 中引号的多层嵌套使用技巧
    本文详细介绍了在 JavaScript 编程中如何处理引号的多级嵌套问题,包括双引号、单引号以及转义字符的正确使用方法。 ... [详细]
  • SSE图像算法优化系列三:超高速导向滤波实现过程纪要(欢迎挑战)
    自从何凯明提出导向滤波后,因为其算法的简单性和有效性,该算法得到了广泛的应用,以至于新版的matlab都将其作为标准自带的函数之一了&#x ... [详细]
  • 本文回顾了作者在求职阿里和腾讯实习生过程中,从最初的迷茫到最后成功获得Offer的心路历程。文中不仅分享了个人的面试经历,还提供了宝贵的面试准备建议和技巧。 ... [详细]
author-avatar
美甲控Alily
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有