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中实现常量(Const)功能
Jan 28 Python
Python中文分词实现方法(安装pymmseg)
Jun 14 Python
Python读取一个目录下所有目录和文件的方法
Jul 15 Python
Python遍历文件夹和读写文件的实现代码
Aug 28 Python
Python 遍历子文件和所有子文件夹的代码实例
Dec 21 Python
Python三种遍历文件目录的方法实例代码
Jan 19 Python
解决Django数据库makemigrations有变化但是migrate时未变动问题
May 30 Python
使用python Fabric动态修改远程机器hosts的方法
Oct 26 Python
python使用wxpy轻松实现微信防撤回的方法
Feb 21 Python
Python 堆叠柱状图绘制方法
Jul 29 Python
python实现图像全景拼接
Mar 27 Python
解决Alexnet训练模型在每个epoch中准确率和loss都会一升一降问题
Jun 17 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
ThinkPHP利用PHPMailer实现邮件发送实现代码
2013/09/26 PHP
php数据库的增删改查 php与javascript之间的交互
2017/08/31 PHP
Laravel框架Request、Response及Session操作示例
2019/05/06 PHP
phpmyadmin在宝塔面板里进不去的解决方案
2020/07/06 PHP
[推荐]javascript 面向对象技术基础教程
2009/03/03 Javascript
javascript 另一种图片滚动切换效果思路
2012/04/20 Javascript
js计算精度问题小结
2013/04/22 Javascript
LABjs、RequireJS、SeaJS的区别
2014/03/04 Javascript
jQuery实现下拉框功能实例代码
2016/05/06 Javascript
AngularJS $injector 依赖注入详解
2016/09/14 Javascript
Vue.js render方法使用详解
2017/04/05 Javascript
nodejs mysql 实现分页的方法
2017/06/06 NodeJs
基于Vue实例对象的数据选项
2017/08/09 Javascript
Angular2 组件间通过@Input @Output通讯示例
2017/08/24 Javascript
JS使用tween.js动画库实现轮播图并且有切换功能
2018/07/17 Javascript
微信小程序实现的3d轮播图效果示例【基于swiper组件】
2018/12/11 Javascript
vue实现todolist基本功能以及数据存储功能实例详解
2019/04/11 Javascript
JavaScript实现网页下拉菜单效果
2020/11/20 Javascript
跟老齐学Python之一个免费的实验室
2014/09/14 Python
python抽取指定url页面的title方法
2018/05/11 Python
一款基于css3和jquery实现的动画显示弹出层按钮教程
2015/01/04 HTML / CSS
html5清空画布方法(三种)
2017/10/16 HTML / CSS
荷兰男士时尚网上商店:Suitable
2017/12/25 全球购物
阿根廷票务网站:StubHub阿根廷
2018/04/13 全球购物
JAVA中的关键字有什么特点
2014/03/07 面试题
什么是跨站脚本攻击
2014/12/11 面试题
寒假思想汇报
2014/01/10 职场文书
人事文员岗位职责
2014/02/16 职场文书
岗位职责风险点
2014/03/12 职场文书
开学典礼演讲稿
2014/05/23 职场文书
国庆65周年演讲稿:回首往昔,展望未来
2014/09/21 职场文书
离婚协议书应该怎么写
2014/10/12 职场文书
2014年学校教学工作总结
2014/12/06 职场文书
庆七一活动简报
2015/07/20 职场文书
Python实现文本文件拆分写入到多个文本文件的方法
2021/04/18 Python
Java 超详细讲解十大排序算法面试无忧
2022/04/08 Java/Android