先扫盲一下什么是正则表达式的贪婪,什么是非贪婪?或者说什么是匹配优先量词,什么是忽略优先量词?

好吧,我也不知道概念是什么,来举个例子吧。
某同学想过滤之间的内容,那是这么写正则以及程序的。
$str = preg_replace('%<script>.+?</script>%i','',$str);//非贪婪
看起来,好像没什么问题,其实则不然。若
$str = '<script<script>alert(document.cookie)</script>>alert(document.cookie)</script>';
那么经过上面的程序处理,其结果为
$str = '<script<script>alert(document.cookie)</script>>alert(document.cookie)</script>';
$str = preg_replace('%<script>.+?</script>%i','',$str);//非贪婪
print_r($str);
//$str 输出为 <script>alert(document.cookie)</script>
仍然达不到他想要的效果。上面的就是非贪婪,也有的叫惰性。其标志非贪婪的标识为量数元字符后面加? ,比如 +?、*?、??(比较特殊,以后的BLOG中,我会写到)等。即标识非贪婪,如果不写?就是贪婪。比如
$str = '<script<script>alert(document.cookie)</script>>alert(document.cookie)</script>';
$str = preg_replace('%<script>.+</script>%i','',$str);//非贪婪
print_r($str);
//$str 输出为 <script 只有这些了,好像还是不太合适,哈,您知道如何重写那个正则吗?
以上为贪婪,非贪婪的区别介绍。下面,聊下贪婪、非贪婪引起的回溯问题。先看个小例子。
正则表达式为\w*(\d+),字符串为cfc456n,那么,这个正则匹配的$1是多少??
如果您回答是 456,那么,恭喜你,回答错了,其结果不是456,而是6,您知道为什么吗?
CFC4N来解释一下,当正则引擎用正则\w*(\d+)去匹配字符串cfc456n时,会先用\w*去匹配字符串cfc456n,首先,\w*会匹配字符串cfc456n的所有字符,然后再交给\d+去匹配剩下的字符串,而剩下的没了,这时,\w*规则会不情愿的吐出一个字符,给\d+去匹配,同时,在吐出字符之前,记录一个点,这个点,就是用于回溯的点,然后\d+去匹配n,发现并不能匹配成功,会再次要求\w*再吐出一个字符,\w*会先再次记录一个回溯的点,再吐出一个字符。这时,\w* 匹配的结果只有cfc45了,已经吐出6n了,\d+再去匹配6,发现匹配成功,则会通知引擎,匹配成功了,就直接显示出来了。所以,(\d+)的结果是6,而不是456。
当上面的正则表达式改为 \w*?(\d+)(注意,此处为非贪婪),字符串仍然为cfc456n,那么,这时候,正则匹配的$1是多少??
甲同学回答:结果是 456。
嗯,是的,正确,是456,CFC4N弱弱的问下,为什么是456 呢?
我在来解释一下 为什么是456
正则表达式有条规则,是量词优先匹配,所以\w*?会先去匹配字符串cfc456,由于\w*?是非贪婪,正则引擎会用表达式\w+?每次仅匹配一个字符串,然后再将控制权交给后面的\d+去匹配下一个字符,同时,记录一个点,用于在匹配不成功的时候,返回这里,再次匹配,也就是回溯点。由于\w后面是量词是*,*表示0到无数次,所以,首先是0次,也就是\w*?匹配个空,记录回溯点,将控制权交给\d+,\d+去匹配cfc456n的第一个字符c,然后,匹配失败,于是乎,接着讲控制权交给\w*?去匹配cfc456n的c,\w*?匹配c成功,由于是非贪婪,所以,他每次只匹配一个字符,记录回溯点,然后再将控制权交给\d+匹配f,接着,\d+匹配f再失败,再把控制权给\w*?,\w*?再匹配c,记录回溯点(这时\w*?匹配结果是cfc了),再把控制权给\d+,\d+去匹配4,匹配成功,然后,由于量词是+,就是1到无数次,所以,接着往后匹配,再匹配5,成功,再接着,再匹配6,成功,再接着,继续匹配操作,下一个字符是n,匹配失败,这时,\d+会吧控制权交出去。由于\d+后面已经没有正则表达式了,所以,整个正则表达式宣告匹配完成,其结果就是 cfc456, 其中第一组结果是456。亲爱的同学,您明白刚刚的题目的结果,为什么是456了吗?
好了,您是否从上面的例子了解了贪婪,非贪婪的匹配原理了?那您是否明白您在什么时候需要使用贪婪,非贪婪去处理您的字符串了?
鸟哥的文章里讲到针对表达式、程序为
$reg = "/<script>.*?<\/script>/is"; $str = "<script>********</script>"; //长度大于100014 $ret = preg_repalce($reg, "", $str); //返回NULL
其原因就是回溯太多了,直到造成耗尽栈空间爆栈。
再来看个例子。
字符串
$str = '<script>123456</script>';
正则表达式为
$strRegex1 = '%<script>.+<\/script>%'; $strRegex2 = '%<script>.+?<\/script>%'; $strRegex3 = '%<script>(?:(?!<\/script>).)+<\/script>%';
以上所述是小编给大家介绍的PHP 正则表达式效率 贪婪、非贪婪与回溯分析,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!
# 正则表达式
# 贪婪
# 正则表达式之回溯
# PHP正则表达式的效率 回溯与固化分组
# 小议正则表达式效率 贪婪、非贪婪与回溯
# 编写高质量的js之正确理解正则表达式回溯
# 正则表达式学习教程之回溯引用backreference详解
# 正则表达式之分组的回溯引用问题
# 如何防止JavaScript中的正则表达式回溯
# 浅谈正则表达式回溯陷阱
# 结果是
# 再把
# 再将
# 小编
# 看个
# 为什么是
# 再接
# 您的
# 如果您
# 我在
# 好了
# 我会
# 第一个
# 那是
# 在此
# 不太
# 什么时候
# 错了
# 给大家
相关文章:
如何在宝塔面板中修改默认建站目录?
建站主机数据库如何配置才能提升网站性能?
黑客如何利用漏洞与弱口令入侵网站服务器?
专业企业网站设计制作公司,如何理解商贸企业的统一配送和分销网络建设?
网站视频制作书签怎么做,ie浏览器怎么将网站固定在书签工具栏?
如何用好域名打造高点击率的自主建站?
深圳企业网站制作设计,在深圳如何网上全流程注册公司?
C++时间戳转换成日期时间的步骤和示例代码
如何快速搭建高效WAP手机网站吸引移动用户?
如何在Windows环境下新建FTP站点并设置权限?
建站之星如何保障用户数据免受黑客入侵?
一键制作网站软件下载安装,一键自动采集网页文档制作步骤?
网站制作需要会哪些技术,建立一个网站要花费多少?
Dapper的Execute方法的返回值是什么意思 Dapper Execute返回值详解
制作网站的模板软件,网站怎么建设?
视频网站制作教程,怎么样制作优酷网的小视频?
建站之星客服服务时间及联系方式如何?
如何通过wdcp面板快速创建网站?
如何在云指建站中生成FTP站点?
如何在阿里云高效完成企业建站全流程?
广德云建站网站建设方案与建站流程优化指南
重庆市网站制作公司,重庆招聘网站哪个好?
如何高效配置IIS服务器搭建网站?
建站主机是否属于云主机类型?
建站之星CMS五站合一模板配置与SEO优化指南
建站之星如何配置系统实现高效建站?
常州自助建站费用包含哪些项目?
如何生成腾讯云建站专用兑换码?
制作国外网站的软件,国外有哪些比较优质的网站推荐?
创业网站制作流程,创业网站可靠吗?
如何通过万网虚拟主机快速搭建网站?
如何选择适配移动端的WAP自助建站平台?
如何配置IIS站点权限与局域网访问?
详解jQuery停止动画——stop()方法的使用
股票网站制作软件,网上股票怎么开户?
如何快速上传自定义模板至建站之星?
小自动建站系统:AI智能生成+拖拽模板,多端适配一键搭建
全景视频制作网站有哪些,全景图怎么做成网页?
如何彻底卸载建站之星软件?
建站OpenVZ教程与优化策略:配置指南与性能提升
如何基于云服务器快速搭建网站及云盘系统?
长春网站建设制作公司,长春的网络公司怎么样主要是能做网站的?
大连网站设计制作招聘信息,大连投诉网站有哪些?
c# Task.Yield 的作用是什么 它和Task.Delay(1)有区别吗
如何在IIS中新建站点并配置端口与物理路径?
建站之星后台管理:高效配置与模板优化提升用户体验
建站之星好吗?新手能否轻松上手建站?
如何在IIS中配置站点IP、端口及主机头?
活动邀请函制作网站有哪些,活动邀请函文案?
北京网站制作公司哪家好一点,北京租房网站有哪些?
*请认真填写需求信息,我们会在24小时内与您取得联系。