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之import机制详解
Jul 03 Python
python编写网页爬虫脚本并实现APScheduler调度
Jul 28 Python
详解Python中的变量及其命名和打印
Mar 11 Python
简述:我为什么选择Python而不是Matlab和R语言
Nov 14 Python
python 的 openpyxl模块 读取 Excel文件的方法
Sep 09 Python
python中自带的三个装饰器的实现
Nov 08 Python
Pytorch 实现冻结指定卷积层的参数
Jan 06 Python
PyCharm无法识别PyQt5的2种解决方法,ModuleNotFoundError: No module named 'pyqt5'
Feb 17 Python
PYQT5 vscode联合操作qtdesigner的方法
Mar 24 Python
通过python 执行 nohup 不生效的解决
Apr 16 Python
安装并免费使用Pycharm专业版(学生/教师)
Sep 24 Python
Python tempfile模块生成临时文件和临时目录
Sep 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
建立文件交换功能的脚本(一)
2006/10/09 PHP
CodeIgniter输出中文乱码的两种解决办法
2014/06/12 PHP
php删除左端与右端空格的方法
2014/11/29 PHP
div浮层,滚动条移动,位置保持不变的4种方法汇总
2013/12/11 Javascript
jquery分页插件jpaginate在IE中不兼容问题
2014/04/22 Javascript
编写简单的jQuery提示插件
2014/12/21 Javascript
jQuery实现鼠标悬停显示提示信息窗口的方法
2015/04/30 Javascript
简介JavaScript中Math.cos()余弦方法的使用
2015/06/15 Javascript
Backbone View 之间通信的三种方式
2016/08/09 Javascript
微信小程序使用navigateTo数据传递的实例
2017/09/26 Javascript
vue-router+vuex addRoutes实现路由动态加载及菜单动态加载
2017/09/28 Javascript
ejsExcel模板在Vue.js项目中的实际运用
2018/01/27 Javascript
JavaScript中join()、splice()、slice()和split()函数用法示例
2018/08/24 Javascript
vue实现跳转接口push 转场动画示例
2019/11/01 Javascript
[15:23]教你分分钟做大人:虚空假面
2014/10/30 DOTA
[52:10]LGD vs Optic Supermajor小组赛D组胜者组决赛 BO3 第二场 6.3
2018/06/04 DOTA
详解Python的迭代器、生成器以及相关的itertools包
2015/04/02 Python
python实现从字典中删除元素的方法
2015/05/04 Python
Django处理文件上传File Uploads的实例
2018/05/28 Python
Python3.7 新特性之dataclass装饰器
2019/05/27 Python
简单了解python反射机制的一些知识
2019/07/13 Python
解决Python3下map函数的显示问题
2019/12/04 Python
Python基础之函数原理与应用实例详解
2020/01/03 Python
Python astype(np.float)函数使用方法解析
2020/06/08 Python
Selenium python时间控件输入问题解决方案
2020/07/22 Python
魔幻般冒泡背景的CSS3按钮动画
2016/02/27 HTML / CSS
elf彩妆英国官网:e.l.f. Cosmetics英国(美国平价彩妆品牌)
2017/11/02 全球购物
Shopee新加坡:东南亚与台湾电商平台
2019/01/25 全球购物
历史专业毕业生的自我鉴定
2013/11/15 职场文书
劳动之星获奖感言
2014/02/01 职场文书
大学生职业生涯规划书参考模板
2014/03/05 职场文书
读书小明星事迹材料
2014/05/03 职场文书
彩妆大赛策划方案
2014/05/13 职场文书
党员自评材料范文
2014/12/17 职场文书
高三英语教学计划
2015/01/23 职场文书
flex弹性布局详解
2022/03/20 HTML / CSS