注:本文章为学习过程中对知识点的记录,供自己复习使用,也给大家做个参考,如有错误,麻烦指出,大家共同探讨,互相进步。
爬虫中用正则表达式,多用于实现字符串的检索、替换、匹配验证。
python的re库提供了整个正则表达式的实现。
常用的正则匹配公式可以用在线工具
模式 | 描述 |
\w | 匹配字母、数字及下划线的字符 |
\W | 相反 |
\s | 匹配任意空白字符,等价于[\t\n\r\f] |
\S | 匹配任意非空字符 |
\d | 匹配任意数字,等价于[0-9] |
\D | 匹配任意非数字的字符 |
\A | 匹配字符串开头 |
\Z | 匹配字符串结尾。如果存在换行,只匹配到换行前的结束字符串 |
\z | 匹配字符串结尾。如果存在换行,同事还会匹配换行符 |
\G | 匹配最后匹配完成的位置 |
\n | 匹配一个换行符 |
\t | 匹配一个制表符 |
^ | 匹配一行字符串的开头 |
$ | 匹配一行字符串的结尾 |
. | 匹配任意字符,除了换行符,当re.DOTALL标记被指定时,可以匹配包括换行符的任意字符 |
[…] | 用来表示一组字符,单独列出,例如[amk]用来匹配a、m或k |
[^…] | 匹配不在[]中的字符,例如匹配除了a、b、c之外的字符 |
* | 匹配0个或多个表达式 |
+ | 匹配1个或多个表达式 |
? | 匹配0个或1个前面的正则表达式定义的片段,非贪婪方式 |
{n} | 精确匹配n个前面的表达式 |
{n,m} | 匹配n到m次由前面正则表达式定义的片段,贪婪方式 |
a|b | 匹配a或b |
() | 匹配括号内的表达式,也表示一个组 |
1、match
向它传入要匹配的字符串以及正则表达式,就可以检测这个正则表达式是否和字符串相匹配。
match方法会尝试从字符串的起始位置开始匹配正则表达式,如果匹配,就返回匹配成功的结果;如果不匹配,就返回None。
输入:
import re
content = 'Hello 123 4567 World_This is a Regex Demo'
print(len(content))
result = re.match('^Hello\s\d\d\d\s\d{4}\s\w{10}',content)
print(result)
print(result.group())
print(result.span())
输出:
41
<re.Match object; span=(0, 25), match='Hello 123 4567 World_This'>
Hello 123 4567 World_This
(0, 25)
解析:
re.match返回re_March对象;
group()返回匹配到的内容
span()返回匹配的范围
①匹配目标
可以使用括号()将想提取的字符串括起来。()实际上标记了一个子表达式的开始和结束位置,被标记的每个子表达式一次对应每个分组,调用group方法传入分组的索引即可获取提取结果。
输入:
import re
content = 'Hello 1234567 World_This is a Regex Demo'
result = re.match('^Hello\s(\d+)\sWorld',content)
print(result)
print(result.group())
print(result.group(1))
输出:
<re.Match object; span=(0, 19), match='Hello 1234567 World'>
Hello 1234567 World
1234567
分析:这里索引从1开始。
②通用匹配
万能匹配‘ .*’
其中,‘.’可以匹配任意字符(除换行符),*代表匹配前面的字符无限次,所以它们组合在一起就可以匹配任意字符了。
③贪婪与非贪婪
输入:
content = 'Hello 1234567 World_This is a Regex Demo'
result = re.match('^He.*(\d+).*Demo$',content)
输出:
这里的匹配结果是7
分析:在贪婪匹配下,.*会匹配尽可能多的字符;后面的\d+匹配至少一个数字(因为这里没有指定匹配几个数字)所以采用非贪婪匹配算法就可以匹配到1234566,即.*?
④修饰符
输入:
content ='''Hello 1234567 World_This
is a Regex Demo'''
result = re.match('^He.*?(\d+).*?Demo$',content)
输出:AttributeError错误
分析:多了一个换行符。解决办法,加入修饰符re.S result = re.match('^He.*?(\d+).*?Demo$', content, re.S)
常用修饰符:
修饰符 | 描述 |
re.I | 使匹配对大小写不敏感 |
re.L | 实现本地化识别(locale-aware)匹配 |
re.M | 多行匹配,影响^和$ |
re.S | 使匹配内容包括换行符在内的所有字符 |
re.U | 更具Unicode字符集解析字符。这个标志会影响\w、\W、\b和\B |
re.X | 该标志能够给予你更灵活的格式,以便将正则表达式书写得更易于理解 |
最常用的为re.I和re.S
⑤转义匹配
当遇到特殊字符用/转义即可。
2、search
match方法是从字符串大的开头开始匹配的,如果不从开头匹配,整个匹配就失败了。所以match更适合检测某个字符串是否符合某个正则表达式的规则。search就是解决这个问题的。(由于绝大部分HTML文本包含换行符,所以需要尽量加上re.S修饰符,以免出现匹配不到的问题)
3、findall
search方法可以返回与正则表达式相匹配的第一个字符串。用findall方法可以匹配获取到所有的相匹配的所有字符串。
findall返回结果是列表类型,需要遍历来依次获取每组内容。
4、sub
用于替换文本。
re.sub(‘\d+’, ‘’, content)
第一个参数:替换的目标
第二个参数:替换成的对象
5、compile
将正则字符串编译成正则表达式对象,以便在后面的匹配中复用。
import re
content='2019-10-10 12:00'
pattern=re.compile('\d{2})
result = re.sub(pattern,'',content)
注:上述介绍了常用的方法和匹配规则,如果对其他方法想了解,可自行百度
下一节的httpx多用于处理HTTP/2.0,功能和requests差不多,爬取HTTP/2.0的时候再来学习这一小节。