1 概述
1.1 正则表达式简介
- 概念:又称规则表达式,在代码中常简写为
regex、regexp、RE
, 作用
- 验证数据的有效性(查找)
- 替换文本内容
- 从字符串中提取字符串(爬虫思想)
1.2 正则表达式的构成
- 原子(普通字符,如英文字符)
- 元字符(有特殊功用的字符)
- 模式的修正字符
一个正则表达式中至少包含一个原子。
2 测试工具
- 能够使用
regexbuddy
进行正则验证 --- 因为正则表达式难于读写,容易出错。 使用
- 选择
Python3.6
test
选项卡
- 选择
3 匹配字符
3.1 单个字符
.
匹配任意单个字符 (除\n
)[]
列举,匹配 [] 中列举的内容[ab]
匹配 a 或者 b[a-z]
匹配所有的小写字母[A-Z]
匹配大写字母[0-9]
匹配数字[a-zA-Z]
匹配所有的小写字母和大写字母
\d
匹配所有的数字 等价于 [0-9]\D
非数字\s
空白\S
非空白\w
匹配 字母、数字、下划线 等同于[a-zA-Z0-9_]
\W
非数字、非字母、非下划线
*. 代表转义字符 *
3.2 多个字符
*
表示前一个字符出现 0 次或者 无限次+
表示 前一个字符出现 1 次或者 无限次?
表示 前一个字符出现 0 次或者 1 次 (要不不出现,要不只能出现一次){m}
表示前一个字符,连续出现 m 次{m,n}
表示前一个字符,连续出现最少 m 次,最多 n 次
m 一定要小于 n
3.3 匹配开头结尾
^
的两个作用- 表示以指定字符(后一个)开头
- 用在[]内部,用于取反
$
表示以前一个字符结尾
4 re模块
- re模块的作用: python 提供的用于正则操作的模块
- re模块的使用步骤:
- 导入模块
- 使用 match() 方法进行检测
- 判断是否检测/匹配成功
- 取出匹配的具体内容
4.1 re.match函数
re.match
尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回 none。
函数语法:re.match(pattern, string, flags=0)
函数参数说明:
pattern
: 匹配的正则表达式string
: 要匹配的字符串。flags
: 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。参见:正则表达式修饰符 - 可选标志
match() 方法一旦匹配成功,就是一个 match object 对象,这个对象有以下几种方法:
- group():返回被 RE 匹配的字符串
- start():返回匹配的开始位置
- end():返回匹配结束的位置
- span():返回一个元组包含匹配(开始,结束)的位置
4.2 分组匹配
表达式1|表达式2
:匹配左右任意一个表达式注意:
|
的作用:或者关系,多个正则表达式满足任意一个都可以,即可以多个连用。表达式1|表达式2|表达式3|表达式4|表达式5|...
(ab)
:将括号中的字符作为一个分组,即把括号里看为一个整体。对于 python 的
re.match
,若result = re.match('^\w{4,20}@(126|qq|163)\.com$', '[email protected]')
,可以使用result.group(1)
查看具体匹配的哪一个,是126 或 qq 或 163
。其中result.group(num)
中的num
代表正则表达式中的第几个括号\num
:引用分组 num 匹配到的字符串为了防止转义字符的作用,在实际中可以将字符串前面加上
r
,result = re.match(r'^<(html)>.*</\1>$', '<html>sfsaefafoshfioaghjhrhvifhgi</html>')
(?P<name>)
:分组起别名(?P<name>)
:分组起别名语法(?P=name)
:引用别名为 name 分组匹配到的字符串
作用就是给分组起别名使其更加有意义,以便记忆和引用。
例如:
result = re.match(r'^<(?P<name1>[a-z0-9]+)><(?P<name2>[a-z0-9]+)>.*</(?P=name2)></(?P=name1)>$', '<html><h1>sfsaefhvifhgi</h1></html>')
4.3 re.search方法
re.search
扫描整个字符串并返回第一个成功的匹配。匹配成功 re.search
方法返回一个匹配的对象,否则返回 None。
函数语法:re.search(pattern, string, flag=0)
函数参数说明:
- pattern:匹配的正则表达式
- string:要匹配的字符串
- flags:标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。参见:正则表达式修饰符 - 可选标志
search() 方法一旦匹配成功,就是一个 search object 对象,这个对象有以下几种方法:
- group():返回被 RE 匹配的字符串
- start():返回匹配的开始位置
- end():返回匹配结束的位置
- span():返回一个元组包含匹配(开始,结束)的位置
re.match
与re.search
的区别与联系:
- 区别:
re.match
只匹配字符串的开始
,如果字符串开始不符合正则表达式,则匹配失败,函数返回 None,而re.search
匹配整个字符串
,直到找到一个匹配。- 联系:两者的语法重合度非常高,用法几乎相同。
4.4 re.findall方法
re.findall
在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果有多个匹配模式,则返回元组列表,如果没有找到匹配的,则返回空列表。
注意: match 和 search 是匹配一次 findall 匹配所有。
函数语法:
re.findall(pattern, string, flag=0)
或
pattern.findall(string,[, pos[, endpos]])
函数参数说明:
pattern
:匹配模式。string
:待匹配的字符串。pos
:可选参数,指定字符串的起始位置,默认为 0。endpos
:可选参数,指定字符串的结束位置,默认为字符串的长度。
4.5 re.sub方法
re.sub
用于替换字符串中的匹配项,返回的是替换的字符串。
函数语法:re.sub(pattern, rep1, string, count=0, flags=0)
函数参数说明:
pattern
: 正则中的模式字符串。repl
: 替换的字符串,也可为一个函数。string
: 要被查找替换的原始字符串。count
: 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。flags
: 编译时用的匹配模式,数字形式。
前三个为必选参数,后两个为可选参数。
- 扩展,多行字符串的定义:
a = """aaaaaaaa
bbbbbbbbbbb
cccccccccc
dddddddddd
eeeeeeeeee"""
4.5 re.split方法
split 方法按照能够匹配的子串将字符串分割后返回列表
函数语法:re.split(pattern, string[, maxsplit=0, flag=0])
函数参数说明:
pattern
:匹配的正则表达式string
:要匹配的字符串maxsplit
:分割次数,maxsplit=1 分割一次,默认为 0,不限制次数。flags
:标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。参见:正则表达式修饰符 - 可选标志
4.6 贪婪与非贪婪
- 贪婪:默认,表示在满足正则的情况尽可能多的取内容
- 非贪婪:表示在满足正则的情况下,尽可能少的取内容
- 贪婪的转变为非贪婪: 在
*、? 、+、{}
的后面再加上?
就可以了
Python 里数量词默认是贪婪的(在少数语言里也可能是默认非贪婪),总是尝试匹配尽可能多的字符,非贪婪则是相反,总是尝试匹配尽可能少的字符。例如:
result = re.match('aaa\d+', 'aaa1234')
贪婪的匹配结果为aaa1234
,而非贪婪的匹配结果为aaa1
非贪婪常用在爬虫里获取链接,例如:
<script type="text/javascript" src="https://dss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/js/lib/jquery-1-edb203c114.10.2.js" style="box"></script>
,src=".*"
贪心结果为:src="https://dss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/js/lib/jquery-1-edb203c114.10.2.js" style="box"
,src=".*?"
非贪心结果为:src="https://dss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/js/lib/jquery-1-edb203c114.10.2.js"
4.7 r的作用
Python 中在字符串的前面加上 r
表示让字符串中的 \
(转义字符)不起作用,表示为原生字符的含义,即一个斜杠 \