python正则中最短匹配实现代码


Posted in Python onJanuary 16, 2018

下面从一个例子入手:

利用正则表达式解析下面的XML/HTML标签:

<composer>Wolfgang Amadeus Mozart</composer>
<author>Samuel Beckett</author> 
<city>London</city>

希望自动格式化重写为:

composer: Wolfgang Amadeus Mozart
author: Samuel Beckett
city: London

一个代码是这样的形式:

#coding:utf-8 
import re 
s="""<composer>WolfgangAmadeus Mozart</composer> 
   <author>SamuelBeckett</author> 
   <city>London</city>""" 
pattern1=re.compile("<\w+>")  #匹配<>中任意的字符 
pattern2=re.compile(">.+</")  #匹配><中任意的字符 
listNames=pattern1.findall(s) #获取所有满足正则表达式pattern1的字符串的列表 
listContents=pattern2.findall(s) #获取所有满足正则表达式pattern2的字符串的列表 
#由于xml是规范的,所以是一一对应(对于错误输入,暂时不考虑) 
for i in range(len(listNames)): 
  #输出的时候利用切片丢弃多余的符号,如:<>/ 
  print(listNames[i][1:len(listNames[i])-1],":", 
     listContents[i][1:len(listContents[i])-2])

这个代码运行后结果是可以的。

下面我们修改下s的格式:

#coding:utf-8
import re

s="<composer>Wolfgang Amadeus Mozart</composer> <author>Samuel Beckett</author> <city>London</city>"
pattern1=re.compile("<\w+>")  #匹配<>中任意的字符
# 此模式为非贪婪模式,所以s不是多行也可以匹配
pattern2=re.compile(">.+</")  #匹配><中任意的字符,问号必须加,"?"是非贪婪匹配
listNames=pattern1.findall(s) #获取所有满足正则表达式pattern1的字符串的列表
listContents=pattern2.findall(s) #获取所有满足正则表达式pattern2的字符串的列表

#由于xml是规范的,所以是一一对应(对于错误输入,暂时不考虑)
for i in range(len(listNames)):
  #输出的时候利用切片丢弃多余的符号,如:<>/
  print(listNames[i][1:len(listNames[i])-1],":",
     listContents[i][1:len(listContents[i])-2])

得到的答案如下所示:

python正则中最短匹配实现代码

我们打印一下匹配到的两个结果看一下,修改代码如下:

#coding:utf-8
import re

s="<composer>Wolfgang Amadeus Mozart</composer> <author>Samuel Beckett</author> <city>London</city>"
pattern1=re.compile("<\w+>")  #匹配<>中任意的字符
# 此模式为非贪婪模式,所以s不是多行也可以匹配
pattern2=re.compile(">.+</")  #匹配><中任意的字符,问号必须加,"?"是非贪婪匹配
listNames=pattern1.findall(s) #获取所有满足正则表达式pattern1的字符串的列表
listContents=pattern2.findall(s) #获取所有满足正则表达式pattern2的字符串的列表

print(listNames)
print(listContents)

#由于xml是规范的,所以是一一对应(对于错误输入,暂时不考虑)
for i in range(len(listNames)):
  #输出的时候利用切片丢弃多余的符号,如:<>/
  print(listNames[i][1:len(listNames[i])-1],":",
     listContents[i][1:len(listContents[i])-2])

显示结果如下:

python正则中最短匹配实现代码

从第一个箭头显示可以看出,这个处理是对的,那么看第二个箭头,这个匹配的结果显然是不对的了,那么是什么原因呢?
这是因为在正则中,‘*'、‘+'、‘?'这些是贪婪匹配,如用 a*,操作结果是尽可能多地匹配模式。所以当你试着匹配一对对称的定界符,如 HTML 标志中的尖括号。匹配单个 HTML 标志的模式不能正常工作,因为 .* 的本质是“贪婪”的 。在这种情况下,解决方案是使用不贪婪的限定符 *?、+?、?? 或 {m,n}?,尽可能匹配小的文本。

那么代码可以修改如下:

#coding:utf-8
import re

s="<composer>Wolfgang Amadeus Mozart</composer> <author>Samuel Beckett</author> <city>London</city>"
pattern1=re.compile("<\w+?>")  #匹配<>中任意的字符
# 此模式为非贪婪模式,所以s不是多行也可以匹配
pattern2=re.compile(">.+?</")  #匹配><中任意的字符,问号必须加,"?"是非贪婪匹配
listNames=pattern1.findall(s) #获取所有满足正则表达式pattern1的字符串的列表
listContents=pattern2.findall(s) #获取所有满足正则表达式pattern2的字符串的列表

#由于xml是规范的,所以是一一对应(对于错误输入,暂时不考虑)
for i in range(len(listNames)):
  #输出的时候利用切片丢弃多余的符号,如:<>/
  print(listNames[i][1:len(listNames[i])-1],":",
     listContents[i][1:len(listContents[i])-2])

最后,用分组对代码的正则进行优化一下,如下:

#coding:utf-8
import re

s="<composer>Wolfgang Amadeus Mozart</composer><author>Samuel Beckett</author><city>London</city>"
pattern1=re.compile("<(\w+?)>")  #匹配<>中任意的字符
# 此模式为非贪婪模式,所以s不是多行也可以匹配
pattern2=re.compile("<\w+?>(.+?)</\w+?>")  #匹配<a>...</a>中任意的字符,问号必须加,"?"是非贪婪匹配
listNames=pattern1.findall(s) #获取所有满足正则表达式pattern1的字符串的列表
listContents=pattern2.findall(s) #获取所有满足正则表达式pattern2的字符串的列表

#由于xml是规范的,所以是一一对应(对于错误输入,暂时不考虑)
for i in range(len(listNames)):
  print(listNames[i],":",
     listContents[i])

这篇文章就介绍到这,大家可以多参考三水点靠木以前发布的关于python 正则表达式的相关内容。

Python 相关文章推荐
Python实现微信公众平台自定义菜单实例
Mar 20 Python
详细解析Python当中的数据类型和变量
Apr 25 Python
Python数据分析之双色球统计两个红和蓝球哪组合比例高的方法
Feb 03 Python
Python实现的三层BP神经网络算法示例
Feb 07 Python
使用实现XlsxWriter创建Excel文件并编辑
May 04 Python
Python Pywavelet 小波阈值实例
Jan 09 Python
python and or用法详解
Jun 26 Python
Flask框架学习笔记之路由和反向路由详解【图文与实例】
Aug 12 Python
pytorch-RNN进行回归曲线预测方式
Jan 14 Python
解决pytorch多GPU训练保存的模型,在单GPU环境下加载出错问题
Jun 23 Python
python实现移动木板小游戏
Oct 09 Python
Numpy中np.max的用法及np.maximum区别
Nov 27 Python
Python程序员面试题 你必须提前准备!
Jan 16 #Python
详解python使用递归、尾递归、循环三种方式实现斐波那契数列
Jan 16 #Python
Python+tkinter模拟“记住我”自动登录实例代码
Jan 16 #Python
Python利用字典将两个通讯录文本合并为一个文本实例
Jan 16 #Python
Python爬虫爬取一个网页上的图片地址实例代码
Jan 16 #Python
Python+Turtle动态绘制一棵树实例分享
Jan 16 #Python
Python实现七彩蟒蛇绘制实例代码
Jan 16 #Python
You might like
php+iframe实现隐藏无刷新上传文件
2012/02/10 PHP
PHP+MySQL删除操作实例
2015/01/21 PHP
基于Swoole实现PHP与websocket聊天室
2016/08/03 PHP
Thinkphp框架开发移动端接口(1)
2016/08/18 PHP
SlideView 图片滑动(扩展/收缩)展示效果
2010/08/01 Javascript
BootStrap table使用方法分析
2016/11/08 Javascript
基于javascript实现的快速排序
2016/12/02 Javascript
你不知道的 javascript【推荐】
2017/01/08 Javascript
Vue响应式添加、修改数组和对象的值
2017/03/20 Javascript
Angular使用Md5加密的解决方法
2017/09/16 Javascript
nodejs的安装使用与npm的介绍
2019/09/11 NodeJs
vue使用better-scroll实现滑动以及左右联动
2020/06/30 Javascript
了不起的11个JavaScript代码重构最佳实践小结
2021/01/11 Javascript
python使用matplotlib绘制柱状图教程
2017/02/08 Python
python检查目录文件权限并修改目录文件权限的操作
2020/03/11 Python
python实现一个猜拳游戏
2020/04/05 Python
django 外键创建注意事项说明
2020/05/20 Python
Python 使用Opencv实现目标检测与识别的示例代码
2020/09/08 Python
利用Python过滤相似文本的简单方法示例
2021/02/03 Python
html5嵌入内容_动力节点Java学院整理
2017/07/07 HTML / CSS
canvas实现扭蛋机动画效果的示例代码
2018/10/17 HTML / CSS
美国畅销的跑步机品牌:ProForm
2017/02/06 全球购物
电子信息毕业生自荐信
2013/11/16 职场文书
元旦促销方案
2014/03/15 职场文书
求职意向书
2014/04/01 职场文书
《一个小村庄的故事》教学反思
2014/04/13 职场文书
安全生产月活动总结
2014/05/04 职场文书
妈妈活动方案
2014/08/15 职场文书
2014年租房协议书范本
2014/10/30 职场文书
职工年度考核评语
2014/12/31 职场文书
政协工作总结2015
2015/05/20 职场文书
婚宴父母致辞
2015/07/27 职场文书
2019大学生暑期实习心得总结
2019/08/21 职场文书
2019年健身俱乐部的创业计划书
2019/08/26 职场文书
Python查找算法的实现 (线性、二分,分块、插值查找算法)
2022/04/24 Python
分享很少见很有用的SQL功能CORRESPONDING
2022/08/05 MySQL