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访问纯真IP数据库的代码
May 19 Python
python client使用http post 到server端的代码
Feb 10 Python
python使用os模块的os.walk遍历文件夹示例
Jan 27 Python
Python跳出循环语句continue与break的区别
Aug 25 Python
python实现颜色空间转换程序(Tkinter)
Dec 31 Python
Python matplotlib画图实例之绘制拥有彩条的图表
Dec 28 Python
解决Python 中英文混输格式对齐的问题
Jul 16 Python
对Python中class和instance以及self的用法详解
Jun 26 Python
解决python ThreadPoolExecutor 线程池中的异常捕获问题
Apr 08 Python
Python yield生成器和return对比代码实例
Apr 20 Python
Python爬虫回测股票的实例讲解
Jan 22 Python
golang中的空接口使用详解
Mar 30 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答题类应用接口实例
2015/02/09 PHP
php验证手机号码
2015/11/11 PHP
PHP实现简单ajax Loading加载功能示例
2016/12/28 PHP
php+mysql开发中的经验与常识小结
2019/03/25 PHP
PHP常量define和const的区别详解
2019/05/18 PHP
PHP单例模式实例分析【防继承,防克隆操作】
2019/05/22 PHP
给网站上的广告“加速”显示的方法
2007/04/08 Javascript
js实现翻页后保持checkbox选中状态的实现方法
2012/11/03 Javascript
Jquery 选中表格一列并对表格排序实现原理
2012/12/15 Javascript
JS小游戏之象棋暗棋源码详解
2014/09/25 Javascript
jQuery实现拖动调整表格单元格大小的代码实例
2015/01/13 Javascript
举例讲解JavaScript substring()的使用方法
2015/11/09 Javascript
JavaScript中的this到底是什么(一)
2015/12/09 Javascript
javascript深拷贝和浅拷贝详解
2017/02/14 Javascript
JS表单数据验证的正则表达式(常用)
2017/02/18 Javascript
使用Node.js实现RESTful API的示例
2017/08/01 Javascript
JS装饰器函数用法总结
2018/04/21 Javascript
用原生JS实现爱奇艺首页导航栏代码实例
2019/09/19 Javascript
Node.js API详解之 Error模块用法实例分析
2020/05/14 Javascript
Python自动化测试工具Splinter简介和使用实例
2014/05/13 Python
用C++封装MySQL的API的教程
2015/05/06 Python
Python多线程和队列操作实例
2015/06/21 Python
PyCharm代码格式调整方法
2018/05/23 Python
python爬虫之自制英汉字典
2019/06/24 Python
Python Django中的STATIC_URL 设置和使用方式
2020/03/27 Python
Python写捕鱼达人的游戏实现
2020/03/31 Python
Python函数递归调用实现原理实例解析
2020/08/11 Python
运行python提示no module named sklearn的解决方法
2020/11/29 Python
家长寄语大全
2014/04/02 职场文书
国际贸易专业求职信
2014/06/04 职场文书
学生安全责任书范本
2014/07/24 职场文书
迎国庆演讲稿
2014/09/05 职场文书
升职自荐信怎么写
2015/03/05 职场文书
2019秋季运动会口号
2019/06/25 职场文书
Python基本的内置数据类型及使用方法
2022/04/13 Python
Nginx本地配置SSL访问的实例教程
2022/05/30 Servers