《python3网络爬虫开发实战 第二版》之基本库的使用-正则表达式 详解
创始人
2025-05-28 01:56:03
0

文章目录

  • 正则表达式
    • 正则表达式介绍
    • match
      • 匹配目标 group
      • 通用匹配 .*
      • 贪婪匹配与非贪婪匹配
      • 修饰符
      • 常见的修饰符
      • 转义匹配
    • search
    • findall
    • sub
    • compile

正则表达式

正则表达式介绍

正则表达式是用来处理字符串的强大工具,有自己特定的语法结构。
可以使用正则表达式进行字符串的检索,替换,匹配验证
对于爬虫来说,使用正则表达式可以简化从HTML提取信息的步骤
匹配URL的正则表达式[a-zA-Z]+://[^\s]*

match

match 方法会尝试从字符串的起始位置开始匹配正则表达式,如果匹配,就返回匹配成功的结果;如果不匹配,就返回None。
实例如下:

def match_test():import recontent = 'Hello 123 45678 World_This is a Regex Demo'result = re.match('^Hello\s\d\d\d\s\d{5}\s\w{10}', content)print(result)  # 返回匹配的结果print(result.group())  # 返回匹配到的内容print(result.span())   # 匹配的范围, 匹配到的结果字符串在原字符串中的位置范围

实例执行的结果如下图所示

在这里插入图片描述

'^Hello\s\d\d\d\s\d{5}\s\w{10}'
^ 表示匹配字符串的开头
\d 表示数字 \d\d\d 表示连续三个数字
\d{5} 表示连续5个数字,这种方式更简单一些
\s 表示一个空格
\w{10} 表示匹配10个字母以及下划线。

匹配目标 group

使用match方法可以实现匹配,
如果从一段文本中提取出E-mail 地址或电话号码,
可以使用括号()将想要提取的字符串括起来。
() 实际上标记了一个子表达式的开始和结束文职,被标记的每个子表达式一次对应每个分组,调用group方法传入分组的索引即可获取提取结果。
实例如下:
实例中的\d+ 表示至少一个数字,至多不封顶

def match_test1():import recontent = 'Hello 1234567 World_Test 45897546 is a regex demo'result = re.match('^Hello\s(\d+)\sWorld_Test\s(\d+)', content)print(result)print('不带序号',result.group(), sep='\t')print('序号为0',result.group(0),sep='\t')print('序号为1', result.group(1),sep='\t')print('序号为2', result.group(2),sep='\t')

实例运行的结果如下图所示
从运行的结果可以看出,不带序号与序号为0时输出的结果是一致的,都是匹配到的完整的字符串
想要提取的子字符串,其索引应当从1开始,而不是0

在这里插入图片描述

通用匹配 .*

前文的空白字符使用\s,数字使用\d,这样写比较复杂
有一个万能匹配就是.* .可以匹配除了换行符之外的任意字符 * 表示前一个字符可以无限次
我们使用.* 来进行匹配,实例代码如下

def match_test2():import recontent = 'Hello 1234567 World_Test 45897546 is a regex demo'result = re.match('^Hello.*is', content)print(result)print(result.group())  # 返回匹配到的内容print(result.span())   # 匹配的范围, 匹配到的结果字符串在原字符串中的位置范围

匹配的结果如下图所示
在这里插入图片描述

贪婪匹配与非贪婪匹配

.*会匹配尽可能多的字符--------> 贪婪匹配
.*?会匹配尽可能少的字符-------> 非贪婪匹配

通过一个实例来对比贪婪匹配与非贪婪匹配的不同
实例目标:匹配目标字符串中的所有的数字

def match_test3():import recontent = 'Hello 1234567 World_Test is a regex demo'result1 = re.match('^Hello.*(\d+)', content)   # 使用.* 来匹配 Hello后面的空格result2 = re.match('^Hello.*?(\d+)', content)  # 使用.*?来匹配 Hello后面的空格result3 = re.match('^Hello.*?(\d+).*?', content)  # 使用.*?匹配后面的字符串result4 = re.match('^Hello.*?(\d+).*', content)   # 使用.* 匹配后面的字符串print('.*匹配空格:', result1.group(1))print('.*?匹配空格:', result2.group(1))print('.*?匹配尾字符串:', result3)print('.*匹配尾字符串:', result4)

代码执行的结果如下图所示:

在这里插入图片描述

从代码运行的结果可以看出:
.* 尽可能匹配更多的字符串,由于\d+ 至少有一个数字,就留下了一个数字7留给\d+进行匹配
.*?尽可能匹配更少的字符串, 由于\d+可以把所有的数字都匹配上,因此.*? 就匹配上了一个空格
在进行字符串末尾匹配的时候,由于.*? 尽可能少地匹配,因此就一个不匹配,就出现第三种结果
在进行字符串末尾匹配的时候,由于.* 尽可能多地匹配,因此所有的字符都匹配上了,就出现了第四种结果

修饰符

如果一个字符串中存在换行符,那么在使用.*或者.*?就匹配不上了
修饰符re.S 可以使.*匹配包括换行符在内的所有字符。
实例代码如下:

def match_test4():import recontent = '''Hello 1234567 World_Test is a regex demo'''result = re.match('^Hello.*?(\d+).*', content, re.S)print(result.group())

代码执行的结果如图所示
在这里插入图片描述

常见的修饰符

修饰符描述
re.I使匹配对大小写不敏感
re.M多行匹配,影响^以及$
re.S匹配包括换行符在内的所有字符
re.U根据Unicode字符集解析字符。会影响\w, \W, \b, \B

转义匹配

在使用.*进行字符匹配的时候,如果目标字符串中本身就含有.怎么办?
只需要在用作正则匹配模式的特殊字符时,在此字符之前加\转义一下即可。
以匹配网址为例,实例如下:

def match_test5():import recontent = '(百度) www.baidu.com'result = re.match('\(百度\) www\.baidu\.com', content)print(result)

代码执行的结果如下图所示
在这里插入图片描述

search

match方法是从自字符串的开头开始匹配的,如果开头不匹配,整个匹配就失败了。
因此match方法在使用时,需要考虑目标字符串开头的内容
更适合检测某个字符串是否符合某个正则表达式的规则

search方法在匹配时会扫描整个字符串,然后返回第一个匹配成功的结果。
在匹配时,search方法会依次以每个字符作为开头扫描字符串,直到找到第一个符合规则的字符串,然后返回匹配内容
如果扫描完还没有找到符合规则的字符串,就返回None
search方法的用法与match方法类似。
需要注意的是,在对HTML文本进行匹配时,由于HTML文本包含换行符,因此需要加上re.S修饰符,以免出现匹配不到的问题

findall

search 方法获取得到的是与正则表达式相匹配的第一个字符串
如果想要获取与正则表达式相匹配的所有字符串,就需要用到findall方法。

sub

前面提到的match,search,findall三个方法都是通过正则表达式进行查找
使用sub可以通过正则表达式对字符串进行修改
例如将一个字符串中的数字换成空格,实例代码如下:

def sub_test():import recontent = 'hijs2jjhj34bjhg6kj3kj7hg'result = re.sub('\d+', ' ', content)print(result)

代码执行的结果如下图所示
在这里插入图片描述

compile

这个方法可以将正则字符串变异成正则你倒是对象,以便在后面的匹配中复用
实例代码如下:

def compile_test():import recontent1 = '2019-02-21 12:12'content2 = '2019-02-24 12:17'content3 = '2019-02-25 12:18'content4 = '2019-02-26 12:19'pattern = re.compile('\d{2}:\d{2}')result1 = re.sub(pattern, '', content1)result2 = re.sub(pattern, '', content2)result3 = re.sub(pattern, '', content3)result4 = re.sub(pattern, '', content4)print(result1, result2, result3, result4)

代码运行的结果如图所示

在这里插入图片描述

相关内容

热门资讯

元旦简短小诗歌 元旦简短小诗歌  元旦节马上就要到了,快乐的元旦节是大家都喜欢的节日。下面是小编整理收集的元旦简短小...
婕妤的诗歌 关于婕妤的诗歌  1.祖国请听我说  我想伏在你的肩头  轻抚你百年沧桑的肋骨  我想贴在你的唇边 ...
木兰香遮不住伤诗歌赏析 木兰香遮不住伤诗歌赏析  在平时的学习、工作或生活中,大家对诗歌都再熟悉不过了吧,诗歌一般饱含丰富的...
2023年端午节的经典现代诗... 农历五月初五是我国的传统节日端午节,这个节日有两千年的历史了,下面是小编为大家收集的关于2021年端...
小学生经典诗歌 小学生经典诗歌大全  中国古代不合乐的称为诗,合乐的称为歌,现代一般统称为诗歌。  1、《月亮》  ...
诗歌黄河落日 诗歌黄河落日(精选5篇)  “君不见,黄河之水天上来,奔流到海不复还。”浩瀚壮阔的黄河,奔腾澎湃,形...
爱祖国的诗歌 爱祖国的诗歌五篇  1、《国泰民安》  作者: 大王  位高貂裘贵,  无一忧国疾!  如昨清末恨,...
2020仿写艾青诗歌《我爱这... 艾青的诗常用比喻、象征等手法,借助某一形象抒发感情,但他的诗中所表现的自然景物,表现的意象,大都被人...
关于母亲节的诗歌 ■写给母亲的诗作者:冰心母亲,好久以来就想为你写一首诗但写了好多次还是没有写好母亲,为你写的这首诗我...
城市的黄昏诗歌 城市的黄昏诗歌  每一个人都有他的故事  故事里的主角却永远只有他自己  不管变换多少城市和空间  ...
描写长江的诗词名句 关于描写长江的诗词名句(精选110句)  无论是在学校还是在社会中,大家都经常接触到诗歌吧,诗歌一般...
天青色等烟雨的诗歌 天青色等烟雨的诗歌  无论是在学校还是在社会中,大家对诗歌都再熟悉不过了吧,诗歌节奏上鲜明有序,音谐...
花间梦事的诗歌 花间梦事的诗歌  有你的晨曦多么美  我轻轻踮一下脚尖  就能摘下几滴干净明亮的鸟鸣  风,从发间吹...
新年贺词顺口溜 新年贺词顺口溜  新年贺词顺口溜(精选250句)  在不断进步的社会中,大家都对那些朗朗上口的顺口溜...
九张机的经典诗歌 九张机的经典诗歌  一场追逐了一生的爱恋。  穿越历史的嘈杂,静静的还原一段机杼声里的相思。  万千...
中秋节美文 中秋节美文(精选23篇)  随着网络文化的发展,网络文化给美文的概念也赋予了更多的开放自由的元素,好...
父爱的现代诗歌 关于父爱的现代诗歌17篇  在学习、工作乃至生活中,大家都听说过或者使用过一些比较经典的诗歌吧,诗歌...
70年代的美好诗歌 70年代的美好诗歌  一束玫瑰送给你  不老的灵魂忧伤  尘世的风  一点点的掠过  你的发丝飘摆 ...
文言文马说解词归纳 文言文马说解词归纳  在平凡的学习生活中,大家一定都接触过文言文吧?文言文,也就是用文言写成的文章,...
诗歌我希望双语版 诗歌我希望双语版  英文诗歌:希望  Isleepwalktothestars  Believing...