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 文件处理注意事项总结
Apr 10 Python
通过Py2exe将自己的python程序打包成.exe/.app的方法
May 26 Python
python实现pdf转换成word/txt纯文本文件
Jun 07 Python
python pip源配置,pip配置文件存放位置的方法
Jul 12 Python
Python 实例方法、类方法、静态方法的区别与作用
Aug 14 Python
python3 实现的对象与json相互转换操作示例
Aug 17 Python
django中使用事务及接入支付宝支付功能
Sep 15 Python
wxPython电子表格功能wx.grid实例教程
Nov 19 Python
django框架ModelForm组件用法详解
Dec 11 Python
python求解汉诺塔游戏
Jul 09 Python
scrapy头部修改的方法详解
Dec 06 Python
Pyhton模块和包相关知识总结
May 12 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 文件上传进度条的两种实现方法的代码
2007/11/25 PHP
兼容PHP5的PHP目录管理函数库
2008/07/10 PHP
PHP从FLV文件获取视频预览图的方法
2015/03/12 PHP
php使用自带dom扩展进行元素匹配的原理解析
2020/05/29 PHP
PHP快速导出百万级数据到CSV或者EXCEL文件
2020/11/27 PHP
浅析Prototype的模板类 Template
2011/12/07 Javascript
关于使用 jBox 对话框的提交不能弹出问题解决方法
2012/11/07 Javascript
js渐变显示渐变消失示例代码
2013/08/01 Javascript
Node.js静态文件服务器改进版
2016/01/10 Javascript
关于List.ToArray()方法的效率测试
2016/09/30 Javascript
jQuery实现页面滚动时智能浮动定位
2017/01/08 Javascript
基于js中style.width与offsetWidth的区别(详解)
2017/11/12 Javascript
vue 自动化路由实现代码
2019/09/03 Javascript
jQuery与原生JavaScript选择HTML元素集合用法对比分析
2019/11/26 jQuery
如何实现iframe父子传参通信
2020/02/05 Javascript
vue.js实现点击图标放大离开时缩小的代码
2021/01/27 Vue.js
python中sys.argv参数用法实例分析
2015/05/20 Python
windows下ipython的安装与使用详解
2016/10/20 Python
Python实现多线程HTTP下载器示例
2017/02/11 Python
利用Python循环(包括while&amp;for)各种打印九九乘法表的实例
2017/11/06 Python
python pytest进阶之conftest.py详解
2019/06/27 Python
Python打开文件、文件读写操作、with方式、文件常用函数实例分析
2020/01/07 Python
Tensorflow 模型转换 .pb convert to .lite实例
2020/02/12 Python
python有序查找算法 二分法实例解析
2020/02/18 Python
使用python图形模块turtle库绘制樱花、玫瑰、圣诞树代码实例
2020/03/16 Python
python实现手势识别的示例(入门)
2020/04/15 Python
jupyter notebook远程访问不了的问题解决方法
2021/01/11 Python
前端canvas水印快速制作(附完整代码)
2019/09/19 HTML / CSS
新加坡领先的时尚生活方式零售品牌:CHARLES & KEITH
2018/01/16 全球购物
AOP的定义以及作用
2013/09/08 面试题
学校百日安全生产活动总结
2014/07/05 职场文书
堂吉诃德读书笔记
2015/06/30 职场文书
超级实用的公文标题大全!
2019/07/19 职场文书
小学语文教师竞聘演讲稿范文
2019/08/09 职场文书
win10安装配置nginx的过程
2021/03/31 Servers
Python Flask请求扩展与中间件相关知识总结
2021/06/11 Python