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 相关文章推荐
使用Python3中的gettext模块翻译Python源码以支持多语言
Mar 31 Python
Python中的Descriptor描述符学习教程
Jun 02 Python
浅谈django开发者模式中的autoreload是如何实现的
Aug 18 Python
关于Django显示时间你应该知道的一些问题
Dec 25 Python
Python比较2个时间大小的实现方法
Apr 10 Python
OpenCV+Python--RGB转HSI的实现
Nov 27 Python
python报错: 'list' object has no attribute 'shape'的解决
Jul 15 Python
python使用列表的最佳方案
Aug 12 Python
python实现excel公式格式化的示例代码
Dec 23 Python
python实现代码审查自动回复消息
Feb 01 Python
python爬虫scrapy基本使用超详细教程
Feb 20 Python
Python机器学习之基础概述
May 19 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 session机制
2011/07/17 PHP
apache mysql php 源码编译使用方法
2012/05/03 PHP
php中选择什么接口(mysql、mysqli)访问mysql
2013/02/06 PHP
ExtJs 3.1 XmlTreeLoader Example Error
2010/02/09 Javascript
Web开发之JavaScript
2012/03/29 Javascript
Javascript 学习笔记之 对象篇(二) : 原型对象
2014/06/24 Javascript
DOM基础教程之事件类型
2015/01/20 Javascript
使用jquery操作session方法分享
2015/01/22 Javascript
对jquery的ajax进行二次封装以及ajax缓存代理组件:AjaxCache详解
2016/04/11 Javascript
jQuery获取与设置iframe高度的方法
2016/08/01 Javascript
jquery网页日历显示控件calendar3.1使用详解
2016/11/24 Javascript
JavaScript制作弹出层效果
2016/12/02 Javascript
微信小程序 实现列表项滑动显示删除按钮的功能
2017/04/13 Javascript
js上传图片预览的实现方法
2017/05/09 Javascript
详解npm 配置项registry修改为淘宝镜像
2018/09/07 Javascript
AjaxFileUpload.js实现异步上传文件功能
2019/04/19 Javascript
vue+element-ui表格封装tag标签使用插槽
2020/06/18 Javascript
python每次处理固定个数的字符的方法总结
2013/01/29 Python
用Python脚本生成Android SALT扰码的方法
2013/09/18 Python
Python的内存泄漏及gc模块的使用分析
2014/07/16 Python
Python按行读取文件的简单实现方法
2016/06/22 Python
python3实现zabbix告警推送钉钉的示例
2019/02/20 Python
django之自定义软删除Model的方法
2019/08/14 Python
Python中生成一个指定长度的随机字符串实现示例
2019/11/06 Python
python中如何使用insert函数
2020/01/09 Python
Python字典深浅拷贝与循环方式方法详解
2020/02/09 Python
Python通过两个dataframe用for循环求笛卡尔积
2020/04/29 Python
利用CSS3实现折角效果实例源码
2016/09/28 HTML / CSS
娇韵诗加拿大官网:Clarins加拿大
2017/11/20 全球购物
文秘专业应届生求职信
2014/05/26 职场文书
优质服务口号
2014/06/11 职场文书
专科生就业求职信
2014/06/22 职场文书
四风问题对照检查材料
2014/09/22 职场文书
授权委托书
2015/01/28 职场文书
功夫熊猫观后感
2015/06/10 职场文书
2015年清剿火患专项行动工作总结
2015/07/27 职场文书