爬虫学习记录 -正则表达式

227 阅读4分钟

这是我参与2022首次更文挑战的第21天,活动详情查看:2022首次更文挑战

买了崔庆才老师的书,已经在学了在学了.每天进步...21天习惯养成

文章详细代码ref:code

常用的正则表达式的用法介绍

match匹配

举例子:

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())

结果:

image.png 这个是调用了正则表达式来匹配字符串,^这个符号代表匹配字符串的开头,就是以Hello开头,\s表示匹配空格,\d代表匹配数字,写几个就是匹配几个,太多的数字不能全这么写啊,\d{4},表示可以匹配四个数字,w{10}代表匹配十个字符及下划线. 真的好酷

匹配目标

用match方法可以匹配目标,要是我们想提取匹配的值该怎么办呢:

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))
print(result.span())

这个根据我从上面得到的知识,它的输出应该是一个对象,然后字符串'Hello 1234567 World' .然后不知道,最后是字符串的范围

来看一下输出的结果:

image.png 跟我的预想不一样,首先是输出 对象,这个地方与书上略有不同,书上的对象是_sre.SRE_Match object,我的是re.Match object

关于这个小问题,无伤大雅,不过我去翻了一下文档docs.python.org/3.7/library… 这应该是在3.7版本更新的,因为在3.6版本,对象依然是前一个,在3.7版本后就是我现在输出这个,我目前用的是3.10版本

3.6版本:

image.png

3.7版本:

image.png

再说一下group这个方法,这个是拿到匹配的内容,不给参数拿到的是最大的,给参数表示拿到的是正则表达式中内部括起来的值,很有意思

通用匹配

是为了解决空格全用\s来标识这种问题, 比如上面的代码就可以简写成:

import re

content = 'Hello 123 4567 World_This is a Regex Demo'
result = re.match('^Hello.*Demo$', content)
print(result)
print(result.group())
print(result.span())

$ 这个是匹配末尾的意思,.* 简化了表达式的写法

贪婪匹配与非贪婪匹配

普通的.*是贪婪匹配,.*?是非贪婪匹配, 在字符串中间还是要尽量使用非贪婪,在字符串的末尾要尽量使用用贪婪匹配.

修饰符

  • re.I 匹配对大小写不敏感
  • re.L 本地化识别匹配
  • re.M 多行匹配 会影响^*
  • re.S 匹配内容包含换行符
  • re.U 根据Unicode字符集解析字符,会影响\w,\W,\b,\B
  • re.X 标志更灵活的格式更容易看懂

转义匹配

在想转义的字符前面加上\

search

match 是从字符串的开头开始匹配的,也就是说一旦开头不对,就找不到了,而search是扫描整个字符串返回第一个成功的结果 举个例子:

import re

content = 'Hello 123 4567 World_This is a Regex Demo'
result = re.match('ello.*Demo$', content)
result = re.search('ello.*Demo$', content)
print(result)
print(result.group())
print(result.span())
这个输出的结果会报错,因为找不到
当我们把match换成search就可以成功匹配到

findall

既然上面那个只能返回第一个匹配的结果,那自然就有方法,可以匹配到所有的,这个跟上面的方法用法一直,得到的结果是列表,列表的每个元素的属性是元组.

sub

这个方法可以修改文本

import re

content = '54aK54yr5oiR54ix5L2g'
content = re.sub('\d+', '', content)
print(content)

这个方法将原来字符串的值全部替换了,第一个参数是要修改的值,第二个参数是修改成什么值 好神奇,在实际过程中,先执行sub 再执行findall会方便很多

compile

这个是将正则字符串,编译成正则表达式对象,以便代码复用.

import re

content1 = '2019-12-15 12:00'
content2 = '2019-12-17 12:55'
content3 = '2019-12-22 13:21'
# 这一步变成对象,方便以后使用
pattern = re.compile('\d{2}:\d{2}')
result1 = re.sub(pattern, '', content1)
result2 = re.sub(pattern, '', content2)
result3 = re.sub(pattern, '', content3)
print(result1, result2, result3)

好了,从崔老师的书上就学这么多了,代码来自崔老师的Python3网络爬虫实战第二版,非常厚这本书,学多少记多少.