Python 正则表达式入门(中级篇)


Posted in Python onDecember 07, 2016

初级篇链接:https://3water.com/article/99372.htm

上一篇我们说在这一篇里,我们会介绍子表达式,向前向后查找,回溯引用。到这一篇开始前除了回溯引用在一些场合不可替代以外,大部分情况下的正则表达式你应该都会写了。

1.子表达式

子表达式的概念特别好理解。其实它就是将几个字符的组合形式看做一个大的“字符”。不好理解?举个栗子:我们要匹配类似IP地址这种形式的字符(暂且不考虑数值范围的合理性,这个留作学完之后的思考题吧)。形如192.168.1.1这样的地址我们怎么写表达式呢?

答案一 \d+.?\d+.?\d+.?\d+

不好,一个是太繁琐,另一个是连位数都控制不了

答案二 \d+{1,3}.?\d+{1,3}.?\d+{1,3}.?\d+{1,3}

一般般,复杂但是起码能把位数控制在合理范围

答案三 (\d+{1,3}\.){3}\d+{1,3}\.

利用子表达式,将123.这种数字加小数点看做一个整体字符,对其规定重复匹配的次数,既简洁,效果又好。所以只要你将几个字符组合用圆括号括起来,那么你就可以把一个圆括号内的内容当做一个字符,外面可以加我们之前讲过的所有元字符来控制匹配。

2.向前向后查找

现在,我们终于来到了向前向后查找这一块。为什么说终于来到这了呢?还记得我们在初级篇最开始的例子吗?

假如你在写一个爬虫,你得到了一个网页的HTML源码。其中有一段html

<html><body><h1>hello world</h1></body></html>

你想要把这个hello world提取出来

import re
key = r"<html><body><h1>hello world</h1></body></html>"#这段是你要匹配的文本
p1 = r"(?<=<h1>).+?(?=</h1>)"#这是我们写的正则表达式规则,你现在可以不理解啥意思
pattern1 = re.compile(p1)#我们在编译这段正则表达式
matcher1 = re.search(pattern1,key)#在源文本中搜索符合正则表达式的部分
print matcher1.group(0)#打印出来

这个正则表达式

p1 = r"(?<=<h1>).+?(?=<h1>)"

看到(?<=<h1>) (?=<h1>)了吗?第一个?<=表示在被匹配字符前必须得有<h1>,后面的?=表示被匹配字符后必须有<h1>

简单来说,就是你要匹配的字符是XX,但必须满足形式是AXXB这样的字符串,那么你就可以这样写正则表达式

p = r"(?<=A)XX(?=B)"

匹配到的字符串就是XX。并且,向前查找向后查找不需要必须同时出现。如果你愿意,可以只写满足一个条件。

所以你也不需要记住哪个是向前查找,哪个是向后查找。只要记住?<=后面跟着的是前缀要求,?=后面跟的是后缀要求。

本质上来说,向前查找和向后查找其实是匹配整个字符串,即AXXB,但返回时仅仅返回一个XX。也就是说,如果你愿意,完全可以避开向前向后查找的方式,直接匹配带有前后缀的字符串,然后做字符串切片处理。

3.回溯引用

不同于前面的向前向后查找,这一条有时候你未必绕的过去。在有些情况下,你还必须得用到回溯引用,所以你如果想拥有在实际应用中使用正则表达式,回溯引用是你应该了解和掌握的。

我们还是从最开始的例子来说。

你原本要匹配<h1></h1>之间的内容,现在你知道HTML有多级标题,你想把每一级的标题内容都提取出来。你也许会这样写:

p = r"<h[1-6]>.*?</h[1-6]>"

这样一来,你就可以将HTML页面内所有的标题内容全部匹配出来。即<h1></h1>到<h6></h6>的内容都可以被提取出来。但是我们之前说过,写正则表达式困难的不是匹配到想要的内容,而是尽可能的不匹配到不想要的内容。在这个例子中,很有可能你就会被下面这样的用例玩坏。

比方说

<h1>hello world</h3>

发现后面的</h3>了吗?我们不管是怎么写出来这样的标题的,但实实在在的是我们的正则表达式同样会把这里面的hello world匹配出来。这时候就是回溯引用的重要作用。下面就是一个示例:

import re
key = r"<h1>hello world</h3>"
p1 = r"<h([1-6])>.*?</h\1>"
pattern1 = re.compile(p1)
m1 = re.search(pattern1,key)
print m1.group(0)#这里是会报错的,因为匹配不到,你如果将源字符串改成</h1>

结尾就能看出效果

看到\1了吗?原本那个位置应该是[1-6],但是我们写的是\1,我们之前说过,转义符\干的活就是把特殊的字符转成一般的字符,把一般的字符转成特殊字符。普普通通的数字1被转移成什么了呢?在这里1表示第一个子表达式,也就是说,它是动态的,是随着前面第一个子表达式的匹配到的东西而变化的。比方说前面的子表达式内是[1-6],在实际字符串中找到了1,那么后面的\1就是1,如果前面的子表达式在实际字符串中找到了2,那么后面的\1就是2。

类似的,\2,\3,....就代表第二个第三个子表达式。

所以回溯引用是正则表达式内的一个“动态”的正则表达式,让你根据实际的情况变化进行匹配。

中级篇就到这里,其实正则表达式还有很多细节还没有写出来,也有很多元字符我没有交代,但掌握了纲要,懂得原理之后剩下的就类似于查表构造这种活了。

建议看到这的朋友看看《正则表达式必知必会》,初级篇和这篇中有几个例子也是取材于此。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,同时也希望多多支持三水点靠木!

Python 相关文章推荐
用ReactJS和Python的Flask框架编写留言板的代码示例
Dec 19 Python
Python数据类型详解(二)列表
May 08 Python
python机器学习理论与实战(一)K近邻法
Jan 28 Python
python画折线图的程序
Jul 26 Python
python实现从文件中读取数据并绘制成 x y 轴图形的方法
Oct 14 Python
Python基于matplotlib画箱体图检验异常值操作示例【附xls数据文件下载】
Jan 07 Python
Python使用import导入本地脚本及导入模块的技巧总结
Aug 07 Python
Python中字典与恒等运算符的用法分析
Aug 22 Python
python3使用Pillow、tesseract-ocr与pytesseract模块的图片识别的方法
Feb 26 Python
python多线程和多进程关系详解
Dec 14 Python
python反编译教程之2048小游戏实例
Mar 03 Python
Python使用永中文档转换服务
May 06 Python
Python 正则表达式入门(初级篇)
Dec 07 #Python
Python标准库06之子进程 (subprocess包) 详解
Dec 07 #Python
利用 Monkey 命令操作屏幕快速滑动
Dec 07 #Python
Python深入06——python的内存管理详解
Dec 07 #Python
Python制作钉钉加密/解密工具
Dec 07 #Python
详解Python 数据库 (sqlite3)应用
Dec 07 #Python
Python应用03 使用PyQT制作视频播放器实例
Dec 07 #Python
You might like
PHP面向对象分析设计的经验原则
2008/09/20 PHP
php在程序中将网页生成word文档并提供下载的代码
2012/10/09 PHP
PHP static局部静态变量和全局静态变量总结
2014/03/02 PHP
Thinkphp 中 distinct 的用法解析
2016/12/14 PHP
textarea中的手动换行处理的jquery代码
2011/02/26 Javascript
JavaScript实现拼音排序的方法
2012/11/20 Javascript
jQuery父级以及同级元素查找介绍
2013/09/04 Javascript
js用正则表达式来验证表单(比较齐全的资源)
2013/11/17 Javascript
jquery实现像栅栏一样左右滑出式二级菜单效果代码
2015/08/24 Javascript
jQuery Validate初步体验(二)
2015/12/12 Javascript
jQuery Easyui实现左右布局
2016/01/26 Javascript
jQuery通过deferred对象管理ajax异步
2016/05/20 Javascript
基于jQuery的select下拉框选择触发事件实例分析
2016/11/18 Javascript
浅谈jquery的html方法里包含特殊字符的处理
2016/11/30 Javascript
半个小时学json(json传递示例)
2016/12/25 Javascript
详谈javascript精度问题与调整
2017/07/08 Javascript
JavaScript上传文件时不用刷新页面方法总结(推荐)
2017/08/15 Javascript
如何在vue里面优雅的解决跨域(路由冲突问题)
2019/01/20 Javascript
Angular2使用SVG自定义图表(条形图、折线图)组件示例
2019/05/10 Javascript
使用p5.js临摹动态图形
2019/10/23 Javascript
Vue作用域插槽实现方法及作用详解
2020/07/08 Javascript
js canvas实现俄罗斯方块
2020/10/11 Javascript
RC4文件加密的python实现方法
2015/06/30 Python
Centos下实现安装Python3.6和Python2共存
2018/08/15 Python
如何利用python给图片添加半透明水印
2019/09/06 Python
Django重设Admin密码过程解析
2020/02/10 Python
Python常用外部指令执行代码实例
2020/11/05 Python
基于html5绘制圆形多角图案
2016/04/21 HTML / CSS
JAVA和C++区别都有哪些
2015/03/30 面试题
奥巴马经典演讲稿
2014/09/13 职场文书
护士自荐信怎么写
2015/03/06 职场文书
自主招生专家推荐信
2015/03/26 职场文书
Python 机器学习工具包SKlearn的安装与使用
2021/05/14 Python
pytorch 使用半精度模型部署的操作
2021/05/24 Python
Python如何识别银行卡卡号?
2021/06/10 Python
JavaScript高级程序设计之基本引用类型
2021/11/17 Javascript