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对象的深拷贝和浅拷贝详解
Aug 25 Python
Python使用爬虫猜密码
Feb 19 Python
详解python 发送邮件实例代码
Dec 22 Python
Python编程之序列操作实例详解
Jul 22 Python
python list元素为tuple时的排序方法
Apr 18 Python
Python2.7.10以上pip更新及其他包的安装教程
Jun 12 Python
windows下 兼容Python2和Python3的解决方法
Dec 05 Python
python使用opencv在Windows下调用摄像头实现解析
Nov 26 Python
python 定义类时,实现内部方法的互相调用
Dec 25 Python
使用celery和Django处理异步任务的流程分析
Feb 19 Python
python等差数列求和公式前 100 项的和实例
Feb 25 Python
python 下载文件的几种方法汇总
Jan 06 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
服务器web工具 php环境下
2010/12/29 PHP
Yii2 rbac权限控制之rule教程详解
2016/06/23 PHP
PHP迭代与递归实现无限级分类
2017/08/28 PHP
[JS]点出统计器
2020/10/11 Javascript
js 程序执行与顺序实现详解
2013/05/13 Javascript
javascript 实现字符串反转的三种方法
2013/11/23 Javascript
如何将php数组或者对象传递给javascript
2014/03/20 Javascript
js实现局部页面打印预览原理及示例代码
2014/07/03 Javascript
javascript实现通过表格绘制颜色填充矩形的方法
2015/04/21 Javascript
javascript日期计算实例分析
2015/06/29 Javascript
浅谈Javascript中的函数、this以及原型
2016/10/09 Javascript
微信小程序之仿微信漂流瓶实例
2016/12/09 Javascript
Node.js中多进程模块Cluster的介绍与使用
2017/05/27 Javascript
详解angular 中的自定义指令之详解API
2017/06/20 Javascript
一个简易的js图片轮播效果
2017/07/22 Javascript
本地存储localStorage用法详解
2017/07/31 Javascript
react-native DatePicker日期选择组件的实现代码
2017/09/12 Javascript
js实现控制文件拖拽并获取拖拽内容功能
2018/02/17 Javascript
python实现的简单抽奖系统实例
2015/05/22 Python
Python函数中不定长参数的写法
2019/02/13 Python
详解PANDAS 数据合并与重塑(join/merge篇)
2019/07/09 Python
迪斯尼商品官方网站:ShopDisney
2016/08/01 全球购物
印度民族服装购物网站:BIBA
2019/08/05 全球购物
Lentiamo荷兰:在线订购隐形眼镜、隐形眼镜液和太阳镜
2019/10/25 全球购物
师范毕业生自荐信
2013/10/17 职场文书
合唱兴趣小组活动总结
2014/07/10 职场文书
2014最新党员批评与自我批评材料
2014/09/24 职场文书
乡镇干部个人对照检查材料思想汇报
2014/10/04 职场文书
幼儿园班级工作总结2015
2015/05/25 职场文书
导游词之北京明十三陵
2019/10/28 职场文书
python第三方网页解析器 lxml 扩展库与 xpath 的使用方法
2021/04/06 Python
python之PySide2安装使用及QT Designer UI设计案例教程
2021/07/26 Python
Windows11里微软已经将驱动程序安装位置A盘删除
2021/11/21 数码科技
Python中的tkinter库简单案例详解
2022/01/22 Python
Java虚拟机内存结构及编码实战分享
2022/04/07 Java/Android
MySql如何将查询的出来的字段进行转换
2022/06/14 MySQL