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删除文件示例分享
Jan 28 Python
python图像处理之镜像实现方法
May 30 Python
对python .txt文件读取及数据处理方法总结
Apr 23 Python
Python生成短uuid的方法实例详解
May 29 Python
Python模块的加载讲解
Jan 15 Python
利用Python库Scapy解析pcap文件的方法
Jul 23 Python
python pandas利用fillna方法实现部分自动填充功能
Mar 16 Python
Python OpenCV读取中文路径图像的方法
Jul 02 Python
Pycharm自带Git实现版本管理的方法步骤
Sep 18 Python
python ssh 执行shell命令的示例
Sep 29 Python
python 使用tkinter与messagebox写界面和弹窗
Mar 20 Python
Django框架中表单的用法
Jun 10 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 单引号与双引号的区别
2009/11/24 PHP
php 生成Tab键或逗号分隔的CSV
2016/09/24 PHP
php插件Xajax使用方法详解
2017/08/31 PHP
PHP删除数组中指定下标的元素方法
2018/02/03 PHP
laravel返回统一格式错误码问题
2019/11/04 PHP
JQuery遍历DOM节点的方法
2015/06/11 Javascript
基于Jquery和CSS3制作数字时钟附源码下载(CSS3篇)
2015/11/24 Javascript
利用jQuery的动画函数animate实现豌豆发射效果
2016/08/28 Javascript
浅谈EasyUi ComBotree树修改 父节点选择的问题
2016/11/07 Javascript
Vue.directive自定义指令的使用详解
2017/03/10 Javascript
jquery实现图片放大点击切换
2017/06/06 jQuery
vue-cli如何添加less 以及sass
2017/07/06 Javascript
JS实现的简单标签点击切换功能示例
2017/09/21 Javascript
Vue引用第三方datepicker插件无法监听datepicker输入框的值的解决
2018/01/27 Javascript
Angular中sweetalert弹框的基本使用教程
2018/07/22 Javascript
Vue.js使用axios动态获取response里的data数据操作
2020/09/08 Javascript
[02:28]DOTA2亚洲邀请赛附加赛 RECAP赛事回顾
2015/01/29 DOTA
使用python实现对元素的长截图功能
2019/11/14 Python
python元组的概念知识点
2019/11/19 Python
使用Python第三方库pygame写个贪吃蛇小游戏
2020/03/06 Python
Python猴子补丁Monkey Patch用法实例解析
2020/03/23 Python
超级实用的8个Python列表技巧
2020/08/24 Python
python爬虫scrapy基本使用超详细教程
2021/02/20 Python
详解css position 5种不同的值的用法
2019/07/30 HTML / CSS
纯html5+css3下拉导航菜单实现代码
2013/03/18 HTML / CSS
董事长职责范文
2013/11/08 职场文书
春节晚会主持词
2014/03/24 职场文书
行政监察建议书
2014/05/19 职场文书
乡镇党建工作汇报材料
2014/10/27 职场文书
南京大屠杀观后感
2015/06/02 职场文书
怎样写观后感
2015/06/19 职场文书
学雷锋活动简报
2015/07/20 职场文书
大学生团支书竞选稿
2015/11/21 职场文书
golang协程池模拟实现群发邮件功能
2021/05/02 Golang
铁头也玩根德 YachtBoy YB-230......
2022/04/05 无线电
Java实现带图形界面的聊天程序
2022/06/10 Java/Android