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 相关文章推荐
深入理解NumPy简明教程---数组2
Dec 17 Python
Python正则捕获操作示例
Aug 19 Python
pandas DataFrame数据转为list的方法
Apr 11 Python
python2 与 python3 实现共存的方法
Jul 12 Python
Python I/O与进程的详细讲解
Mar 08 Python
python pillow模块使用方法详解
Aug 30 Python
python 3.6.7实现端口扫描器
Sep 04 Python
python如何实现图片压缩
Sep 11 Python
PyCharm上安装Package的实现(以pandas为例)
Sep 18 Python
python中如何打包用户自定义模块
Sep 23 Python
基于python模拟bfs和dfs代码实例
Nov 19 Python
5个pandas调用函数的方法让数据处理更加灵活自如
Apr 24 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
星际争霸 Starcraft 秘技补丁
2020/03/14 星际争霸
smarty实例教程
2006/11/19 PHP
php实现根据url自动生成缩略图的方法
2014/09/23 PHP
Smarty变量用法详解
2016/05/11 PHP
PHP基于回溯算法解决n皇后问题的方法示例
2017/11/07 PHP
php输出控制函数和输出函数生成静态页面
2019/06/27 PHP
javascript实现全角半角检测的方法
2015/07/23 Javascript
javascript实现动态标签云
2015/10/16 Javascript
js实现String.Fomat的实例代码
2016/09/02 Javascript
jquery事件绑定解绑机制源码解析
2016/09/19 Javascript
使用Require.js封装原生js轮播图的实现代码
2017/06/15 Javascript
React学习笔记之列表渲染示例详解
2017/08/22 Javascript
JavaScript实现的原生态兼容IE6可调可控滚动文字功能详解
2017/09/19 Javascript
详解node+express+ejs+bootstrap构建项目
2017/09/27 Javascript
react-router4 配合webpack require.ensure 实现异步加载的示例
2018/01/18 Javascript
JS实现的简单分页功能示例
2018/08/23 Javascript
微信小程序分享功能onShareAppMessage(options)用法分析
2019/04/24 Javascript
JS Thunk 函数的含义和用法实例总结
2020/04/08 Javascript
Vue两种组件类型:递归组件和动态组件的用法
2020/08/06 Javascript
Python基础之函数用法实例详解
2014/09/10 Python
PyQt5的PyQtGraph实践系列3之实时数据更新绘制图形
2019/05/13 Python
python区分不同数据类型的方法
2019/10/14 Python
对Python中 \r, \n, \r\n的彻底理解
2020/03/06 Python
Python @property及getter setter原理详解
2020/03/31 Python
python opencv角点检测连线功能的实现代码
2020/11/24 Python
美国最大的袜子制造商和零售商:Renfro Socks
2017/09/03 全球购物
英国Office鞋店德国网站:在线购买鞋子、靴子和运动鞋
2018/12/19 全球购物
碧欧泉法国官网:Biotherm法国
2019/10/23 全球购物
Smilodox官方运动服装店:从运动服到健身配件
2020/08/27 全球购物
应聘收银员个人的求职信
2013/11/30 职场文书
升旗仪式演讲稿
2014/05/08 职场文书
2014年政风行风自查自纠报告
2014/10/21 职场文书
2014年社区党建工作总结
2014/11/11 职场文书
2016党性教育学习心得体会
2016/01/21 职场文书
你真的了解redis为什么要提供pipeline功能
2021/06/22 Redis
详解pytorch创建tensor函数
2022/03/22 Python