爬虫系列(五) re的基本使用

时间:2022-06-30 19:23:21

1、简介

究竟什么是正则表达式 (Regular Expression) 呢?可以用下面的一句话简单概括:

正则表达式是一组特殊的 字符序列,由一些事先定义好的字符以及这些字符的组合形成,常常用于 匹配字符串

在 Python 中,re 模块 就是一个用于处理正则表达式的模块,详细信息可以参考 官方文档

另外,这里再给大家推荐一个博主常用的测试正则表达式的网站:http://tool.oschina.net/regex,不妨一试

2、特殊符号

上面说过,正则表达式实际上是由一些事先定义好的字符以及这些字符的组合形成

那么,这些特殊的字符究竟包括什么呢?它们又有怎样的含义呢?具体请看下面的讲解:

  • .:匹配除换行符之外的 所有字符

  • ^:匹配字符串的 开始位置

  • $:匹配字符串的 结束位置

  • *:匹配字符串 零次或多次,在后面加上 ? 表示启用非贪婪模式匹配(默认为贪婪模式)

  • +:匹配字符串 一次或多次,在后面加上 ? 表示启用非贪婪模式匹配(默认为贪婪模式)

  • ?:匹配字符串 零次或一次,在后面加上 ? 表示启用非贪婪模式匹配(默认为贪婪模式)

  • { }:匹配字符串 指定次

    • {M, N} 表示匹配字符串 M~N 次

    • {M,} 表示匹配字符串至少 M 次

    • {,N} 表示匹配字符串至多 N 次

    • {N} 表示匹配字符串 N 次

  • [ ]:匹配 括号内所包含的任意一个字符

    • 若连字符 (-) 出现在字符串中间则表示范围,出现在首位则作普通字符;

    • 若脱字符 (^) 出现在字符串首位则表示排除,出现在中间则作普通字符

  • ( )捕获子组,将括号中的匹配模式作为一个整体被捕获,并作为子组返回

  • (?: )非捕获子组,将括号中的匹配模式作为一个整体被捕获,但不作为子组返回

  • \b:匹配一个 单词边界,单词被定义成字母数字或下横线字符

  • \B:与 \b 相反

  • \d

    • 对于 str 类型,匹配任何 数字字符,包括 [0-9] 以及其它数字字符

    • 对于 str 类型开启 re.ASCII 标志或者 bytes 类型,只匹配 [0-9]

  • \D:与 \d 相反

  • \s

    • 对于 str 类型,匹配任何 空白字符,包括 [\t\n\r\f\v] 以及其它空白字符

    • 对于 str 类型开启 re.ASCII 标志或者 bytes 类型,只匹配 [\t\n\r\f\v]

  • \S:与 \s 相反

  • \w

    • 对于 str 类型,匹配任何 单词字符,包括 [a-zA-Z0-9_] 以及其它单词字符

    • 对于 str 类型开启 re.ASCII 标志或者 bytes 类型,只匹配 [a-zA-Z0-9_]

  • \W:与 \w 相反

下面我们来看一个简单的例子,帮助大家更好的理解正则表达式的匹配方式

匹配整数

^ 匹配开头

-? 匹配减号字符,零次或一次,对应正整数和负整数

[1-9] 匹配 1~9 之间的任意一个数字,确保整数的第一个数字不能为 0

\d* 匹配任意数字字符,零次或多次

$ 匹配结尾

^-?[1-9]\d*$

3、常用方法

(1)match(pattern, string, flags=0)

在 string 起始位置开始匹配 pattern,flags 表示标志位

若匹配成功则返回 SRE_Match 对象,若匹配不成功则返回 None 对象

_sre.SRE_Match 对象常用的方法列举如下:

  • start([group]):返回匹配开始的位置
  • end([group]):返回匹配结束的位置
  • span([group]):返回匹配的范围
  • group(num=0):返回匹配的字符串,若对象中有子组,则加上 num 参数可获取相应子组
>>> import re
>>> result = re.match(r'abc(\d+)', "abc123def456abc789")
>>> type(result)
# <class '_sre.SRE_Match'>
>>> result.start() # 查看匹配的起始位置
# 0
>>> result.end() # 查看匹配的结束位置
# 6
>>> result.span() # 查看匹配的范围
# (0, 6)
>>> result.group() # 查看匹配的字符串
# 'abc123'
>>> result.group(1) # 查看匹配的子组
# '123'

(2)search(pattern, string, flags=0)

在 string 中搜索第一次出现的 pattern,flags 表示标志位

同样的,若匹配成功则返回 SRE_Match对象,若匹配不成功则返回 None对象

>>> import re
>>> result = re.search(r'abc(\d+)', "abc123def456abc789")
>>> type(result)
# <class '_sre.SRE_Match'>
>>> result.span() # 查看匹配的范围
(0, 6)

(3)findall(pattern, string, flags=0)

在 string 中搜索所有符合条件的 pattern,flags 表示标志位

一般情况下,该方法返回匹配内容的 列表,若匹配模式中含有子组,则返回对应的子组列表

>>> import re
>>> result = re.findall(r'abc\d+', "abc123def456abc789") # 不含子组
>>> type(result)
# <class 'list'>
>>> for item in result:
print(item)
# abc123
# abc789
>>> result = re.findall(r'abc(\d+)', "abc123def456abc789") # 含有子组
>>> type(result)
# <class 'list'>
>>> for item in result:
print(item)
# 123
# 789

(4)finditer(pattern, string, flags=0)

在 string 中搜索所有符合的 pattern,flags表示标志位

一般情况下,该方法返回匹配内容的 迭代器对象

>>> import re
>>> result = re.finditer(r'abc(\d+)', "abc123def456abc789")
>>> type(result)
# <class 'callable_iterator'>
>>> for item in result:
print(item)
# <_sre.SRE_Match object; span=(0, 6), match='abc123'>
# <_sre.SRE_Match object; span=(12, 18), match='abc789'>

(5)compile(pattern, flags=0)

编译正则表达式模式为正则表达式对象

通常情况下,如果需要重复使用某个正则表达式,那么可以先将该正则表达式编译成模式对象,以下是参数说明:

  • pattern :匹配模式,建议使用原始字符串表示

  • flags :标志位,用于控制正则表达式的匹配方式,可选值如下,多个值之间用 | 分割:

    • re.I \ re.IGNORECASE:不区分大小写
    • re.L \ re.LOCALE:取决于当前语言环境
    • re.S \ re.DOTALL:使 . 匹配包括换行符在内的所有字符
    • re.M \ re.MULTILINE:使 ^ 匹配字符串的开头和每行的开头,使 $ 匹配字符串的结尾和每行的结尾

该方法返回一个 SRE_Pattern对象,该对象常用的方法如下:

  • match(string[, pos[, endpos]])

    用对象中的匹配模式匹配 string 的起始位置,该方法返回 SRE_Match 对象,用 pos 和 endpos 表示匹配的范围

  • search(string[, pos[, endpos]])

    用对象中的匹配模式匹配 string,该方法返回 SRE_Match 对象,用 pos 和 endpos 表示匹配的范围

  • findall(string[, pos[, endpos]])

    用对象中的匹配模式匹配 string,该方法返回列表,用 pos 和 endpos 表示匹配的范围

  • finditer(string[, pos[, endpos]])

    用对象中的匹配模式匹配 string,该方法返回迭代器,用 pos 和 endpos 表示匹配的范围

【参考资料】

【爬虫系列相关文章】