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实现Youku视频批量下载功能
Mar 14 Python
Python栈算法的实现与简单应用示例
Nov 01 Python
python3.x 将byte转成字符串的方法
Jul 17 Python
django框架实现模板中获取request 的各种信息示例
Jul 01 Python
Python流程控制 while循环实现解析
Sep 02 Python
利用PyCharm操作Github(仓库新建、更新,代码回滚)
Dec 18 Python
在tensorflow中实现去除不足一个batch的数据
Jan 20 Python
python爬取本站电子书信息并入库的实现代码
Jan 20 Python
Python中如何添加自定义模块
Jun 09 Python
Python DES加密实现原理及实例解析
Jul 17 Python
python七种方法判断字符串是否包含子串
Aug 18 Python
总结Pyinstaller打包的高级用法
Jun 28 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
怎么样可以把 phpinfo()屏蔽掉?
2006/11/24 PHP
php 删除无限级目录与文件代码共享
2008/11/22 PHP
一个php导出oracle库的php代码
2009/04/20 PHP
实战mysql导出中文乱码及phpmyadmin导入中文乱码的解决方法
2010/06/11 PHP
php项目中类的自动加载实例讲解
2019/09/12 PHP
JQuery里选择超链接的实现代码
2011/05/22 Javascript
JQuery each打印JS对象的方法
2013/11/13 Javascript
jquery实现鼠标滑过后动态图片提示效果实例
2015/08/10 Javascript
基于Bootstrap实现tab标签切换效果
2020/04/15 Javascript
JS简单实现点击复制链接的方法
2016/08/03 Javascript
Vue.js使用$.ajax和vue-resource实现OAuth的注册、登录、注销和API调用
2017/05/10 Javascript
Vue使用json-server进行后端数据模拟功能
2018/04/17 Javascript
vue中当图片地址无效的时候,显示默认图片的方法
2018/09/18 Javascript
React通过redux-persist持久化数据存储的方法示例
2019/02/14 Javascript
JQuery事件委托原理与用法实例分析
2019/05/13 jQuery
JavaScript实现HTML导航栏下拉菜单
2020/11/25 Javascript
[02:33]2018DOTA2亚洲邀请赛赛前采访——LGD
2018/04/04 DOTA
python如何通过protobuf实现rpc
2016/03/06 Python
python字典的常用操作方法小结
2016/05/16 Python
python事件驱动event实现详解
2018/11/21 Python
使用PyInstaller将Pygame库编写的小游戏程序打包为exe文件及出现问题解决方法
2019/09/06 Python
python多线程实现代码(模拟银行服务操作流程)
2020/01/13 Python
40个你可能不知道的Python技巧附代码
2020/01/29 Python
python中安装django模块的方法
2020/03/12 Python
html5 视频播放解决方案
2016/11/06 HTML / CSS
Monnier Freres中文官网:法国领先的奢侈品配饰在线零售商
2017/11/01 全球购物
广州盈通面试题
2015/12/05 面试题
门卫人员岗位职责
2013/12/24 职场文书
药学职务聘任书
2014/03/29 职场文书
学校安全责任书
2014/04/14 职场文书
机关作风整顿个人整改措施2014
2014/09/17 职场文书
走群众路线剖析材料
2014/10/09 职场文书
法学专业求职信范文
2015/03/19 职场文书
停电放假通知
2015/04/14 职场文书
2015年惩防体系建设工作总结
2015/05/22 职场文书
手写Spirit防抖函数underscore和节流函数lodash
2022/03/22 Javascript