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 19 Python
恢复百度云盘本地误删的文件脚本(简单方法)
Oct 21 Python
python Django的web开发实例(入门)
Jul 31 Python
Django用户认证系统 组与权限解析
Aug 02 Python
让你的Python代码实现类型提示功能
Nov 19 Python
python连接PostgreSQL过程解析
Feb 09 Python
tensorflow的ckpt及pb模型持久化方式及转化详解
Feb 12 Python
解决pymysql cursor.fetchall() 获取不到数据的问题
May 15 Python
如何利用python web框架做文件流下载的实现示例
Jun 02 Python
python3.9.1环境安装的方法(图文)
Feb 02 Python
python 如何在list中找Topk的数值和索引
May 20 Python
详解解Django 多对多表关系的三种创建方式
Aug 23 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 使用MySQL管理Session的回调函数详解
2013/06/21 PHP
PHP从二维数组得到N层分类树的实现代码
2016/10/11 PHP
jquery ajax 简单范例(界面+后台)
2013/11/19 Javascript
jquery将一个表单序列化为一个对象的方法
2014/01/03 Javascript
bootstrap data与jquery .data
2014/07/07 Javascript
NodeJS中利用Promise来封装异步函数
2015/02/25 NodeJs
jQuery实现简单的DIV拖动效果
2016/02/19 Javascript
学做Bootstrap的第一个页面
2016/05/15 HTML / CSS
微信小程序 chooseImage选择图片或者拍照
2017/04/07 Javascript
js中如何完美的解析数据
2018/03/18 Javascript
vue中子组件的methods中获取到props中的值方法
2018/08/27 Javascript
[02:00]DOTA2英雄COSPLAY闹市街头巡游助威2015国际邀请赛
2015/08/02 DOTA
[04:51]TI10典藏宝瓶Ⅱ外观视频展示
2020/08/15 DOTA
[01:00] DOTA2英雄背景故事第五期之重力引力法则谜团
2020/07/16 DOTA
使用Python3 编写简单信用卡管理程序
2016/12/21 Python
详解Golang 与python中的字符串反转
2017/07/21 Python
django用户注册、登录、注销和用户扩展的示例
2018/03/19 Python
python ChainMap的使用和说明详解
2019/06/11 Python
Python实现FM算法解析
2019/06/18 Python
python字符串下标与切片及使用方法
2020/02/13 Python
python 按钮点击关闭窗口的实现
2020/03/04 Python
Python3如何使用tabulate打印数据
2020/09/25 Python
Amaze UI 文件选择域的示例代码
2020/08/26 HTML / CSS
Silk’n激光脱毛器官网:silkn.com
2016/10/06 全球购物
拉斯维加斯城市观光通行证:Las Vegas Pass
2019/05/21 全球购物
世界上最大的冷却器制造商:Igloo Coolers
2019/07/23 全球购物
应届专科生个人的自我评价
2014/01/05 职场文书
职工运动会感言
2014/02/07 职场文书
主持人演讲稿
2014/05/13 职场文书
2014年中职班主任工作总结
2014/12/16 职场文书
2015年电工工作总结
2015/04/10 职场文书
2016年党员读书月活动总结
2016/04/06 职场文书
熟背这些句子,让您的英语口语突飞猛进(135句)
2019/09/06 职场文书
MySQL 聚合函数排序
2021/07/16 MySQL
python_tkinter事件类型详情
2022/03/20 Python
springboot+zookeeper实现分布式锁
2022/03/21 Java/Android