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 相关文章推荐
python基于pygame实现响应游戏中事件的方法(附源码)
Nov 11 Python
使用Nginx+uWsgi实现Python的Django框架站点动静分离
Mar 21 Python
Python搭建APNS苹果推送通知推送服务的相关模块使用指南
Jun 02 Python
tensorflow 获取变量&amp;打印权值的实例讲解
Jun 14 Python
详解Python 切片语法
Jun 10 Python
Python中利用LSTM模型进行时间序列预测分析的实现
Jul 26 Python
python禁用键鼠与提权代码实例
Aug 16 Python
python实现把二维列表变为一维列表的方法分析
Oct 08 Python
爬虫代理池Python3WebSpider源代码测试过程解析
Dec 20 Python
python开发实例之python使用Websocket库开发简单聊天工具实例详解(python+Websocket+JS)
Mar 18 Python
vscode配置anaconda3的方法步骤
Aug 08 Python
Python使用Beautiful Soup(BS4)库解析HTML和XML
Jun 05 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
WINXP下apache+php4+mysql
2006/11/25 PHP
Erlang的运算符(比较运算符,数值运算符,移位运算符,逻辑运算符)
2012/07/23 PHP
php递归json类实例
2014/12/02 PHP
PHP中防止SQL注入方法详解
2014/12/25 PHP
php源码 fsockopen获取网页内容实例详解
2016/09/24 PHP
Yii全局函数用法示例
2017/01/22 PHP
PHP Beanstalkd消息队列的安装与使用方法实例详解
2020/02/21 PHP
PHP字符串和十六进制如何实现互相转换
2020/07/16 PHP
javascript 面向对象编程基础 多态
2009/08/21 Javascript
javascript 时间比较实现代码
2009/10/28 Javascript
得到jQuery detach()后节点中的某个值实现代码
2013/02/05 Javascript
JQuery对class属性的操作实现按钮开关效果
2013/10/11 Javascript
jQuery实现预加载图片的方法
2015/03/17 Javascript
AngularJS 输入验证详解及实例代码
2016/07/28 Javascript
JSP防止网页刷新重复提交数据的几种方法
2016/11/19 Javascript
Vue数字输入框组件使用方法详解
2020/02/10 Javascript
JS+CSS实现3D切割轮播图
2020/03/21 Javascript
详细分析Node.js 多进程
2020/06/22 Javascript
详解JavaScript之Array.reduce源码解读
2020/11/01 Javascript
python关键字and和or用法实例
2015/05/28 Python
python机器学习实战之树回归详解
2017/12/20 Python
Python 编码规范(Google Python Style Guide)
2018/05/05 Python
Python生成器的使用方法和示例代码
2019/03/04 Python
简单了解python代码优化小技巧
2019/07/08 Python
完美解决python3.7 pip升级 拒绝访问问题
2019/07/12 Python
Python内置函数locals和globals对比
2020/04/28 Python
Python3 socket即时通讯脚本实现代码实例(threading多线程)
2020/06/01 Python
英国露营设备和户外服装购物网站:Simply Hike
2019/05/05 全球购物
JPA面试常见问题
2016/11/14 面试题
Servlet都有哪些方法?主要作用是什么?
2014/03/04 面试题
大专会计自我鉴定
2014/02/06 职场文书
优秀少先队员主要事迹材料
2014/05/28 职场文书
中学教师暑期培训方案
2014/08/27 职场文书
奖励申请报告范文
2015/05/15 职场文书
实例讲解Python中sys.argv[]的用法
2021/06/03 Python
Go语言基础切片的创建及初始化示例详解
2021/11/17 Golang