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数据结构链表之单向链表(实例讲解)
Jul 25 Python
Python命令行解析模块详解
Feb 01 Python
解决vscode python print 输出窗口中文乱码的问题
Dec 03 Python
用Python编写一个高效的端口扫描器的方法
Dec 20 Python
浅谈Pycharm中的Python Console与Terminal
Jan 17 Python
Python实现连接MySql数据库及增删改查操作详解
Apr 16 Python
Python read函数按字节(字符)读取文件的实现
Jul 03 Python
如何在Django项目中引入静态文件
Jul 26 Python
python实现人机猜拳小游戏
Feb 03 Python
Python如何操作office实现自动化及win32com.client的运用
Apr 01 Python
Python 制作查询商品历史价格的小工具
Oct 20 Python
python代码实现备忘录案例讲解
Jul 26 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
Windows下利用Gvim写PHP产生中文乱码问题解决方法
2011/04/20 PHP
CodeIgniter连贯操作的底层原理分析
2016/05/17 PHP
php添加数据到xml文件的简单例子
2016/09/08 PHP
php实现的SSO单点登录系统接入功能示例分析
2016/10/12 PHP
thinkphp中AJAX返回ajaxReturn()方法分析
2016/12/06 PHP
thinkphp修改配置进入默认首页的方法
2017/02/07 PHP
php基于session锁防止阻塞请求的方法分析
2017/08/07 PHP
THREE.JS入门教程(4)创建粒子系统
2013/01/24 Javascript
提示$ is not defined错误分析及解决
2013/04/09 Javascript
jquery打开直接跳到网页最下面、最低端实现代码
2013/04/22 Javascript
jQuery 无限级菜单的简单实例
2014/02/21 Javascript
js实现二代身份证号码验证详解
2014/11/20 Javascript
jquery实现简单的自动播放幻灯片效果
2015/06/13 Javascript
Js遍历键值对形式对象或Map形式的方法
2016/08/08 Javascript
详谈jQuery.load()和Jsp的include的区别
2017/04/12 jQuery
微信小程序商城项目之商品属性分类(4)
2017/04/17 Javascript
nodejs操作mongodb的增删改查功能实例
2017/11/09 NodeJs
bootstrap table表格插件之服务器端分页实例代码
2018/09/12 Javascript
jQuery实现的卷帘门滑入滑出效果【案例】
2019/02/18 jQuery
elementUI Tree 树形控件的官方使用文档
2019/04/25 Javascript
JavaScript实现简单日历效果
2020/09/11 Javascript
超详细小程序定位地图模块全系列开发教学
2020/11/24 Javascript
[00:32]2018DOTA2亚洲邀请赛EG出场
2018/04/03 DOTA
Python解析nginx日志文件
2015/05/11 Python
Python import用法以及与from...import的区别
2015/05/28 Python
Python中遍历字典过程中更改元素导致异常的解决方法
2016/05/12 Python
python GUI库图形界面开发之PyQt5树形结构控件QTreeWidget详细使用方法与实例
2020/03/02 Python
Scrapy模拟登录赶集网的实现代码
2020/07/07 Python
浅谈Python爬虫原理与数据抓取
2020/07/21 Python
PIP和conda 更换国内安装源的方法步骤
2020/09/21 Python
pycharm实现猜数游戏
2020/12/07 Python
详解Python遍历列表时删除元素的正确做法
2021/01/07 Python
味多美官网:蛋糕订购,100%使用天然奶油
2017/11/10 全球购物
机电专业个人求职信范文
2013/12/30 职场文书
法定代表人身份证明书
2014/09/10 职场文书
起诉书范文
2015/05/20 职场文书