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操作gmail实例
Jan 14 Python
详细解析Python中__init__()方法的高级应用
May 11 Python
图文讲解选择排序算法的原理及在Python中的实现
May 04 Python
Python实现Mysql数据库连接池实例详解
Apr 11 Python
Python脚本完成post接口测试的实例
Dec 17 Python
Python3 使用pillow库生成随机验证码
Aug 26 Python
Python实现报警信息实时发送至邮箱功能(实例代码)
Nov 11 Python
基于python求两个列表的并集.交集.差集
Feb 10 Python
Python GUI库PyQt5图形和特效样式QSS介绍
Feb 25 Python
解决Python安装cryptography报错问题
Sep 03 Python
Pytorch 图像变换函数集合小结
Feb 01 Python
Django路由层如何获取正确的url
Jul 15 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中常用数组处理方法实例分析
2008/08/30 PHP
php提交post数组参数实例分析
2015/12/17 PHP
php如何控制用户对图片的访问 PHP禁止图片盗链
2016/03/25 PHP
php代码检查代理ip的有效性
2016/08/19 PHP
javascript基于jQuery的表格悬停变色/恢复,表格点击变色/恢复,点击行选Checkbox
2008/08/05 Javascript
一个选择最快的服务器转向代码
2009/04/27 Javascript
jquery 多行文本框(textarea)高度变化
2013/07/03 Javascript
jquery使用each方法遍历json格式数据实例
2015/05/18 Javascript
Angular ng-repeat遍历渲染完页面后执行其他操作详细介绍
2016/12/13 Javascript
vue指令以及dom操作详解
2017/03/04 Javascript
微信小程序开发入门基础教程
2017/04/19 Javascript
Angular实现下载安装包的功能代码分享
2017/09/05 Javascript
微信小程序使用image组件显示图片的方法【附源码下载】
2017/12/08 Javascript
关于Webpack dev server热加载失败的解决方法
2018/02/22 Javascript
vue中axios请求的封装实例代码
2019/03/23 Javascript
了解JavaScript表单操作和表单域
2019/05/27 Javascript
5个你不知道的JavaScript字符串处理库(小结)
2020/06/01 Javascript
[00:32]2018DOTA2亚洲邀请赛出场——VP
2018/04/04 DOTA
操作Windows注册表的简单的Python程序制作教程
2015/04/07 Python
python求质数的3种方法
2018/09/28 Python
python检测文件夹变化,并拷贝有更新的文件到对应目录的方法
2018/10/17 Python
使用python 打开文件并做匹配处理的实例
2019/01/02 Python
python从子线程中获得返回值的方法
2019/01/30 Python
使用celery执行Django串行异步任务的方法步骤
2019/06/06 Python
Flask框架模板继承实现方法分析
2019/07/31 Python
win10系统下python3安装及pip换源和使用教程
2020/01/06 Python
利用python绘制数据曲线图的实现
2020/04/09 Python
浅谈Python协程
2020/06/17 Python
keras 两种训练模型方式详解fit和fit_generator(节省内存)
2020/07/03 Python
Python如何将模块打包并发布
2020/08/30 Python
校园招聘策划书
2014/01/09 职场文书
工程技术员岗位职责
2014/03/02 职场文书
个人自我鉴定总结
2014/03/25 职场文书
小学三八妇女节活动总结
2015/02/06 职场文书
自主招生自荐信范文
2015/03/04 职场文书
幼儿园教师读书笔记
2015/06/29 职场文书