正则表达式 这个词我们常常在爬虫相关的文章中见到,今天,我就简单整理回答下“正则表达式是什么?以及如何使用正则表达式?”这两个问题。
举个例子:找出<span>红色</span>
中的颜色,我们先找规律,发现,我们要提取“红色”,这个文本前后分别是 >
和<
,我们当然可以说这是个规律,通过匹配左边是 >
右边是 <
来提取“红色”。但如果了解网页结构(或者看过网页源代码的)就知道 <...>
这是特有的形式。<span>
是一个行内标签的前半部分。知道这个信息的话,我们就会用想:要提取 "红色" 我们就要找到 <span>
还有 </span>
,这就是规律,我们要先明确这个规律后,我们才能确定我们要写怎么样的匹配规则。不过这里我主要介绍Python怎么写正则表达式,以及不同含义的规则要怎么写。实际的匹配规则可能会很复杂,就是我们找的这个“规律”会比较复杂,既要保证找尽量全的数据,又要保证不找到哪些我们不要的,这里的“红色”这个例子,只是为了辅助大家理解举的小小的例子。
这个函数的用法很简单,导入 re
库,引入匹配规则和待解析文本即可,如下:
import re
# 解析提取的对象
text_ = xxx
res = re.findall(匹配规则,text_)
匹配规则是一串字符串,用一系列的符号组合来表示各式各样的规则,而每个符号的含义都是事先确定好的。通过这样的规则,来实现对原始文本进行提取或过滤。
(1)简单例子
待解析文本 src_text
,规则是 \w\s\w
。
import re
src_text = '''I love you.'''
rule_ = '\w\s\w' # 有时候规则会很长,直接写到findall太冗长,一般单独赋给一个变量
res_text = re.findall(rule_, src_text)
返回结果是:['I l','e y']
,注意两点:匹配结果返回的是一个列表,findall
函数会把所有匹配上规则的字符串找出来。
(2)?的作用:贪婪->非贪婪匹配
这个正则表达式默认都是贪婪匹配,就是如果有 "." "*" "+" 这种可以表示任意长度字符的符号,都是默认匹配尽可能长的字符串出来,加上 "?" 后呢?就只是找从左到右最先匹配上的字符串,属于非贪婪的。
举个例子:待解析文本 src_text
,规则是 .+o
。
import re
src_text = '''I love you.'''
rule_ = '.+o'
res_text = re.findall(rule_, src_text)
返回结果是:['I love yo']
。当规则改为:.+?o
。
import re
src_text = '''I love you.'''
rule_ = '.+?o'
res_text = re.findall(rule_, src_text)
返回结果是:['I lo', 've yo']
。它就是找到第一个匹配上规则的字符串后,再开始,找下一个匹配上规则的字符串,而没有加 "?" 则是尽可能地匹配上最长的字符串。
(3)常用且重要的匹配组合 .*?
这三个符号的组合,表示:重复0次或任意次的任意字符的非贪婪匹配。这个组合能匹配的内容很多,很常用。
举个例子:待解析文本 src_text
,规则是 \s.*?\s
。
import re
src_text = '''I love you.'''
rule_ = '\s.*?\s'
res_text = re.findall(rule_, src_text)
返回结果是:[' love ']
。它将匹配到前后文的字符串返回出来。
(4)括号( )获取式匹配
其实就是匹配并获取括号内的表达式。举个例子,当匹配规则含有不带()的表达式以及带()的表达式,则只返回带()表达式匹配的部分。
例子:待解析文本 src_text
,规则是 \s.*?\s(.*?)u
。
import re
src_text = '''I love you.'''
rule_ = '\s.*?\s(.*?)u'
res_text = re.findall(rule_, src_text)
返回结果是:['yo']
。而前面没有括号()的表达式匹配的内容则没有返回出来,但也是有进行匹配的。
(5)换行符号匹配
我们注意到那个符号含义的表,"." 的含义里面有一句 “换行符除外”,如果要匹配的内容,里面含有换行符,但是我又不知道这个换行符在哪个位置,也不知道有多少个换行符的话,就不能用 “\n” 去匹配,若还是要用 "." 匹配的话,需要在 findall()
函数中加上 re.S
参数即可。re.findall(rule_, src_text,re.S)
(6)匹配符号本身[ ]
看了上面的东西,有人就想问了,那我如果就是要匹配类似 "*" "." "?" 本身呢,那就在这些符号(表达式)的外面括上中括号即可。
推荐阅读: