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使用自定义user-agent抓取网页的方法
Apr 15 Python
Python实现简易端口扫描器代码实例
Mar 15 Python
python中requests使用代理proxies方法介绍
Oct 25 Python
一行代码让 Python 的运行速度提高100倍
Oct 08 Python
用Python解决x的n次方问题
Feb 08 Python
python获取点击的坐标画图形的方法
Jul 09 Python
浅析Windows 嵌入python解释器的过程
Jul 26 Python
深入浅析Python科学计算库Scipy及安装步骤
Oct 12 Python
解决Pytorch训练过程中loss不下降的问题
Jan 02 Python
python zip()函数的使用示例
Sep 23 Python
python爬虫泛滥的解决方法详解
Nov 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
PHP新手上路(十三)
2006/10/09 PHP
PHP正则的Unknown Modifier错误解决方法
2010/03/02 PHP
PHP生成器简单实例
2015/05/13 PHP
PHP封装的Twitter访问类实例
2015/07/18 PHP
php 多进程编程父进程的阻塞与非阻塞实例分析
2020/02/22 PHP
基于jquery的finkyUI插件与Ajax实现页面数据加载功能
2010/12/03 Javascript
Javascript 键盘事件的组合使用实现代码
2012/05/04 Javascript
浅谈JavaScript字符集
2014/05/22 Javascript
javascript 获取HTML DOM父、子、临近节点
2014/06/16 Javascript
JavaScript获取一个范围内日期的方法
2015/04/24 Javascript
jQuery实现的网页换肤效果示例
2016/09/20 Javascript
AngularJS1.X学习笔记2-数据绑定详解
2017/04/01 Javascript
vue 2.0项目中如何引入element-ui详解
2017/09/06 Javascript
Vue.js实现tab切换效果
2019/07/24 Javascript
ES6 新增的创建数组的方法(小结)
2019/08/01 Javascript
vue项目,代码提交至码云,iconfont的用法说明
2020/07/30 Javascript
[02:15]2014DOTA2国际邀请赛 赛后退役选手回顾
2014/08/01 DOTA
[13:25]VP vs VICI (BO3)
2018/06/07 DOTA
Python实现的数据结构与算法之快速排序详解
2015/04/22 Python
介绍Python中的__future__模块
2015/04/27 Python
Python过滤列表用法实例分析
2016/04/29 Python
浅谈numpy中linspace的用法 (等差数列创建函数)
2017/06/07 Python
在python中利用KNN实现对iris进行分类的方法
2018/12/11 Python
Python 多个图同时在不同窗口显示的实现方法
2019/07/07 Python
Python reversed反转序列并生成可迭代对象
2020/10/22 Python
Python利用matplotlib绘制折线图的新手教程
2020/11/05 Python
萨克斯第五大道英国:Saks Fifth Avenue英国
2019/04/01 全球购物
华为消费者德国官方网站:HUAWEI德国
2020/11/03 全球购物
计算机专业学生求职信分享
2013/12/15 职场文书
考试不及格的检讨书
2014/01/22 职场文书
详细的大学生创业计划书模板
2014/01/27 职场文书
校园十大歌手策划书
2014/02/01 职场文书
反邪教警示教育方案
2014/05/13 职场文书
2014年保险业务员工作总结
2014/12/23 职场文书
煤矿隐患排查制度
2015/08/05 职场文书
详解nginx.conf 中 root 目录设置问题
2021/04/01 Servers