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的常见命令注入威胁
Feb 18 Python
Python中的数学运算操作符使用进阶
Jun 20 Python
Python中字典(dict)合并的四种方法总结
Aug 10 Python
运用TensorFlow进行简单实现线性回归、梯度下降示例
Mar 05 Python
朴素贝叶斯Python实例及解析
Nov 19 Python
python使用pygame框架实现推箱子游戏
Nov 20 Python
python实现在多维数组中挑选符合条件的全部元素
Nov 26 Python
Python进程的通信Queue、Pipe实例分析
Mar 30 Python
基于Tensorflow的MNIST手写数字识别分类
Jun 17 Python
Python切片列表字符串如何实现切换
Aug 06 Python
Python+logging输出到屏幕将log日志写入文件
Nov 11 Python
Python基础之教你怎么在M1系统上使用pandas
May 08 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
解析posix与perl标准的正则表达式区别
2013/06/17 PHP
php session_start()出错原因分析及解决方法
2013/10/28 PHP
php带抄送和密件抄送的邮件发送方法
2015/03/20 PHP
详谈phpAdmin修改密码后拒绝访问的问题
2017/04/03 PHP
解决windows上php xdebug 无法调试的问题
2020/02/19 PHP
初探jquery——表单应用范例
2007/02/20 Javascript
javascript 控制 html元素 显示/隐藏实现代码
2009/09/01 Javascript
Javascript select下拉框操作常用方法
2009/11/09 Javascript
js解析与序列化json数据(二)序列化探讨
2013/02/01 Javascript
基于JavaScript 类的使用详解
2013/05/07 Javascript
Js Jquery创建一个弹出层可加载一个页面
2014/05/08 Javascript
详解JavaScript UTC时间转换方法
2016/01/07 Javascript
实例讲解javascript注册事件处理函数
2016/01/09 Javascript
JS简单测试循环运行时间的方法
2016/09/04 Javascript
原生js实现无限循环轮播图效果
2017/01/20 Javascript
AngularJS 表单验证手机号的实例(非必填)
2017/11/12 Javascript
详解Angular调试技巧之报错404(not found)
2018/01/31 Javascript
使用vue2.6实现抖音【时间轮盘】屏保效果附源码
2019/04/24 Javascript
Python去除列表中重复元素的方法
2015/03/20 Python
用Python制作在地图上模拟瘟疫扩散的Gif图
2015/03/31 Python
Python使用ftplib实现简易FTP客户端的方法
2015/06/03 Python
python机器学习实战之树回归详解
2017/12/20 Python
python进程和线程用法知识点总结
2019/05/28 Python
Django中的用户身份验证示例详解
2019/08/07 Python
python提取照片坐标信息的实例代码
2019/08/14 Python
python 变量初始化空列表的例子
2019/11/28 Python
python3连接mysql获取ansible动态inventory脚本
2020/01/19 Python
django rest framework serializer返回时间自动格式化方法
2020/03/31 Python
Python项目跨域问题解决方案
2020/06/22 Python
美国尼曼百货官网:Neiman Marcus
2019/09/05 全球购物
法律专业推荐信范文
2013/11/29 职场文书
军校本科大学生自我评价
2014/01/14 职场文书
文案策划岗位个人自我评价(范文)
2019/08/08 职场文书
一劳永逸彻底解决pip install慢的办法
2021/05/24 Python
pytorch通过训练结果的复现设置随机种子
2021/06/01 Python
Win11 Build 22000.829更新补丁KB5015882发布(附更新修复内容汇总)
2022/07/15 数码科技