python 正则表达式贪婪模式与非贪婪模式原理、用法实例分析


Posted in Python onOctober 14, 2019

本文实例讲述了python 正则表达式贪婪模式与非贪婪模式原理、用法。分享给大家供大家参考,具体如下:

之前未接触过正则表达式,今日看python网络爬虫的源码,里面一行正则表达式匹配的代码初看之下,不是很理解,代码如下:

myItems = re.findall('<div.*?class="content".*?title="(.*?)">(.*?)</div>',unicodePage,re.S)

“.*?”这种匹配方式,按理解应该是匹配任意字符0个或多个(re.S模式,“.”可以匹配“\n”),但是这个“?”总觉的在这儿是多余的,既然不理解,就敲代码试试:

import re
patern = re.compile('www\..*')
match1 = patern.match("www.baidu.com")
if match1:
  print(match1.group())
else:
  print("match1 don't match")
#output
>>> ==================RESTART =============================
>>> 
www.baidu.com

这个结果,应该说是意料之中,加个“?”呢?

import re
patern = re.compile('www\..*?')
match1 = patern.match("www.baidu.com")
if match1:
  print(match1.group())
else:
  print("match1 don't match")
#output
>>> ==================RESTART =============================
>>> 
www.

竟然是这个结果。。。“.?”一个字符都没匹配,按“.”、“”、“?”的匹配理解,也就是“*”“?”均匹配前面字符0次,才会是这个结果,可是为啥就是0次了?

这就是正则表达式贪婪模式和非贪婪模式:

  • 贪婪模式,总是尝试匹配尽可能多的字符;
  • 非贪婪模式则相反,总是尝试匹配尽可能少的字符。

Python里数量词默认是贪婪的,这就解释了第一个匹配实验,输出结果为”www.baidu.com”(贪婪模式),也就是说第二个匹配实验是非贪婪模式,仅仅因为加了“?”,继续实验

import re
patern = re.compile('www\..?')
match1 = patern.match("www.baidu.com")
if match1:
  print(match1.group())
else:
  print("match1 don't match")
#output
>>> ==================RESTART =============================
>>> 
www.b

此次匹配结果,显然是贪婪模式。奇怪了,也就是“?”的特殊组合才是非贪婪模式。

网上搜索得如下说明:

标准量词修饰的子表达式,在可匹配可不匹配的情况下,总会先尝试进行匹配,称这种方式为匹配优先,或者贪婪模式。此前介绍的一些量词,“{m}”、“{m,n}”、“{m,}”、“?”、“*”和“+”都是匹配优先的。
一些NFA正则引擎支持忽略优先量词,也就是在标准量词后加一个“?”,此时,在可匹配可不匹配的情况下,总会先忽略匹配,只有在由忽略优先量词修饰的子表达式,必须进行匹配才能使整个表达式匹配成功时,才会进行匹配,称这种方式为忽略优先,或者非贪婪模式。忽略优先量词包括“{m}?”、“{m,n}?”、“{m,}?”、“??”、“*?”和“+?”。

显然“*?”的组合是非贪婪模式,猜想正确,原来如此啊。

Python 相关文章推荐
在漏洞利用Python代码真的很爽
Aug 26 Python
Python中使用copy模块实现列表(list)拷贝
Apr 14 Python
详细解析Python中的变量的数据类型
May 13 Python
Pyqt实现无边框窗口拖动以及窗口大小改变
Apr 19 Python
Python实现按中文排序的方法示例
Apr 25 Python
Django Aggregation聚合使用方法解析
Aug 01 Python
Python3 实现爬取网站下所有URL方式
Jan 16 Python
解决springboot yml配置 logging.level 报错问题
Feb 21 Python
Python基于类路径字符串获取静态属性
Mar 12 Python
django admin管理工具自定义时间区间筛选器DateRangeFilter介绍
May 19 Python
python 下载m3u8视频的示例代码
Nov 11 Python
python飞机大战游戏实例讲解
Dec 04 Python
Python协程操作之gevent(yield阻塞,greenlet),协程实现多任务(有规律的交替协作执行)用法详解
Oct 14 #Python
Python 闭包,函数分隔作用域,nonlocal声明非局部变量操作示例
Oct 14 #Python
win10子系统python开发环境准备及kenlm和nltk的使用教程
Oct 14 #Python
python web框架Flask实现图形验证码及验证码的动态刷新实例
Oct 14 #Python
执行Django数据迁移时报 1091错误及解决方法
Oct 14 #Python
解析Python3中的Import
Oct 13 #Python
Python英文文章词频统计(14份剑桥真题词频统计)
Oct 13 #Python
You might like
国外比较好的几个的Php开源建站平台小结
2010/04/22 PHP
PHP序列号生成函数和字符串替换函数代码
2012/06/07 PHP
PHP图片等比例缩放生成缩略图函数分享
2014/06/10 PHP
PHP中读取文件的几个方法总结(推荐)
2016/06/03 PHP
PHP数组实例详解
2016/06/26 PHP
php mysql实现mysql_select_db选择数据库
2016/12/30 PHP
js函数的引用, 关于内存的开销
2012/09/17 Javascript
我的NodeJs学习小结(一)
2014/07/06 NodeJs
js获取浏览器基本信息大全
2014/11/27 Javascript
js实现键盘Enter键提交表单的方法
2015/05/27 Javascript
在HTML中插入JavaScript代码的示例
2015/06/03 Javascript
Flow之一个新的Javascript静态类型检查器
2015/12/21 Javascript
JavaScript必知必会(七)js对象继承
2016/06/08 Javascript
Vue中使用clipboard实现复制功能
2018/09/05 Javascript
AJAX在JQuery中的应用详解
2019/01/30 jQuery
Vue-cli3多页面配置详解
2020/03/22 Javascript
解决vue刷新页面以后丢失store的数据问题
2020/08/11 Javascript
[01:01:42]Secret vs Optic Supermajor 胜者组 BO3 第二场 6.4
2018/06/05 DOTA
python递归打印某个目录的内容(实例讲解)
2017/08/30 Python
浅谈Python用QQ邮箱发送邮件时授权码的问题
2018/01/29 Python
python监控键盘输入实例代码
2018/02/09 Python
详解Python中where()函数的用法
2018/03/27 Python
python整合ffmpeg实现视频文件的批量转换
2019/05/31 Python
感知器基础原理及python实现过程详解
2019/09/30 Python
pytorch-神经网络拟合曲线实例
2020/01/15 Python
HTML5 Canvas API中drawImage()方法的使用实例
2016/03/25 HTML / CSS
印度购物网站:TATA CLiQ
2017/11/23 全球购物
护理职业生涯规划书
2014/01/24 职场文书
毕业生如何写自我鉴定
2014/03/15 职场文书
计算机专业求职信
2014/06/02 职场文书
药店促销活动总结
2014/07/10 职场文书
2015年测量员工作总结
2015/05/23 职场文书
幼儿教师师德培训心得体会
2016/01/09 职场文书
同学聚会开幕词
2019/04/02 职场文书
如何书写邀请函?
2019/06/24 职场文书
深入理解CSS 中 transform matrix矩阵变换问题
2021/08/30 HTML / CSS