Python与正则表达式

参考资料:
1.菜鸟教程-Python 3 正则表达式,网址:https://www.runoob.com/python3/python3-reg-expressions.html
2.《Python从小白到大牛》,作者关东升,清华大学出版社
3.《Python数据分析基础》,作者[美]Clinton W. Brownley,译者陈光欣,中国工信出版集团,人民邮电出版社

简述正则表达式

  正则表达式(Regular Expression)是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。在Python中,正则表达式的应用非常广泛,如数据挖掘、数据分析、网络爬虫、输入有效性验证等。
  re模块使Python拥有全部的正则表达式功能。我们使用下面的语句来导入该模块:

import re

正则表达式字符串

  正则表达式字符串由普通字符和元字符组成。
  普通字符是按照字符字面意义表示的字符。元字符是预先定义好的一些特殊字符,如\w+\.都属于元字符。
  下面是一些基本元字符:

字符 说明
\ 转义符号
. 表示任意一个字符
+ 表示重复一次或多次
* 表示重复零次或多次
? 表示重复零次或一次
| 选择符号,表示“或”
{} 定义量词
[] 定义字符类
() 定义分组
^ 表示取反,或匹配一行的开始
$ 匹配一行的结束

  上面提到了元字符^$,它们可以匹配一行字符串的开始和结束。当以^开始时,要求一行字符串的开始位置匹配;当以$位置结束时,要求一行字符串的结束位置匹配。需要注意的是,正则表达式\w+@qq\.com^\w+@qq\.com$是不同的。
  定义字符类需要使用元字符[]。例如说我们想在输入的字符串中匹配Python或python,则可以使用正则表达式[Pp]ython
  在正则表达式中指定不想出现的字符,可以在字符类之前加^符号进行字符类取反。比如说,正则表达式[^0123456789]表示输入的字符串中出现非0~9数字即匹配,也就是出现在[0123456789]之外的任意字符即匹配。
  上面所说的正则表达式[^0123456789]写起来非常麻烦。事实上,我们引入区间的概念之后,这种连续的字符可以使用区间来表示。区间使用连字符-表示。例如[0123456789]可以采用区间表示为[0-9][^0123456789]可以采用区间表示为[^0-9]。区间也可以表示连续的英文字母字符类,例如[a-z]表示所有小写字符类,[A-Z]表示所有大写字母字符类。除此之外,也可以表示多个不同区间,例如[A-Za-z0-9]表示所有字母和数字字符类,[0-36-8]表示0、1、2、3、6、7、8几个数字字符组成的字符类。
  正则表达式提供了预定义字符类。预定义字符类如下表所示:

字符 说明
. 匹配任意一个字符
\\ 匹配反斜杠\字符
\n 匹配换行符
\r 匹配回车符
\f 匹配一个换页符
\t 匹配一个水平制表符
\v 匹配一个垂直制表符
\s 匹配一个空格符(等价于[\t\n\r\f\v])
\S 匹配一个非空格符(等价于[^\s])
\d 匹配一个数字字符(等价于[0-9])
\D 匹配一个非数字字符(等价于[^0-9])
\w 匹配任何语言的单词字符(包括英文字母、亚洲文字等)、数字和下划线等字符,如果正则表达式编译标志设置为ASCII,则只匹配[a-zA-Z0-9_]
\W 等价于[^\w]

量词

  在正则表达式中,元字符只能匹配显示一次字符或字符串。如果想要匹配显示多次字符或字符串,可以使用量词。
  正则表达式中的量词如下表所示:

字符 说明
? 出现零次或一次
* 出现零次或多次
+ 出现一次或多次
{n} 出现n次
{n,m} 至少出现n次但不超过m次
{n,} 至少出现n次

  下面是一个量词的使用示例代码:

import re

m = re.search(r'\d?', '87654321')               # 出现数字一次
print(m)                                        # 匹配字符'8'

m = re.search(r'\d?', 'ABC')                    # 出现数字零次
print(m)                                        # 匹配字符''

m = re.search(r'\d*', '87654321')               # 出现数字多次
print(m)                                        # 匹配字符'87654321'

m = re.search(r'\d*', 'ABC')                    # 出现数字零次
print(m)                                        # 匹配字符''

m = re.search(r'\d+', '87654321')               # 出现数字多次
print(m)                                        # 匹配字符'87654321'

m = re.search(r'\d+', 'ABC')
print(m)                                        # 不匹配

m = re.search(r'\d{8}', '87654321')             # 出现数字8次
print(m)                                        # 匹配字符'87654321'

m = re.search(r'\d{8}', 'ABC')
print(m)                                        # 不匹配

m = re.search(r'\d{7,8}', '87654321')          # 出现数字8次
print(m)                                        # 匹配字符'87654321'

m = re.search(r'\d{9,}', '87654321')
print(m)                                        # 不匹配

  输出结果如下:

<re.Match object; span=(0, 1), match='8'>
<re.Match object; span=(0, 0), match=''>
<re.Match object; span=(0, 8), match='87654321'>
<re.Match object; span=(0, 0), match=''>
<re.Match object; span=(0, 8), match='87654321'>
None
<re.Match object; span=(0, 8), match='87654321'>
None
<re.Match object; span=(0, 8), match='87654321'>
None

  量词还可以细分为贪婪量词和懒惰量词。贪婪量词会尽可能多地匹配字符,懒惰量词会尽可能少地匹配字符。大多数计算机语言的正则表达式量词默认是贪婪量词,如果要使用懒惰量词,在量词之后加?即可。
  下面是一个示例代码:

import re

m = re.search(r'\d{5,8}', '87654321')               # 出现数字8次
print(m)                                            # 匹配字符'87654321'

m = re.search(r'\d{5,8}?', '87654321')              # 出现数字5次
print(m)                                            # 匹配字符'87654'

  输出结果如下:

<re.Match object; span=(0, 8), match='87654321'>
<re.Match object; span=(0, 5), match='87654'>

分组

  量词只能重复显示一个字符,如果想让一个字符串作为整体使用量词,可以将这个字符串放到()中,这就是分组,也被称作子表达式。
  下面是一个使用分组的示例代码:

import re

p = r'(121){2}'
m = re.search(p, '121121abcabc')
print(m)                                # 匹配
print(m.group())                        # 返回匹配字符串
print(m.group(1))                       # 获得第一组内容
p = r'(\d{3,4})-(\d{7,8})'
m = re.search(p, '010-87654321')
print(m)                                # 匹配
print(m.group())                        # 返回匹配字符串
print(m.groups())                       # 获得所有组内容

  输出结果如下:

<re.Match object; span=(0, 6), match='121121'>
121121
121
<re.Match object; span=(0, 12), match='010-87654321'>
010-87654321
('010', '87654321')

  在Python中访问分组时,除了可以通过组编号访问,还可以通过组名访问。这需要我们在正则表达式中为组命名。组命名通过在组开头添加?P<分组名>实现。
  在正则表达式中,反向引用语法是\组编号。组编号从1开始。
  前面所说的分组称为捕获分组。捕获分组的子表达式结果被暂时保存到内存中,以备表达式或其他程序通过组编号或组名进行引用。但是有时,我们并不想引用子表达式的匹配结果,不想捕获匹配结果,只是将小括号作为一个整体进行匹配。这个时候我们就可以使用非捕获分组。在组开头使用?:可以实现非捕获分组。

Python的re模块

re.search()函数

  re.search()函数在输入字符串中查找,返回第一个匹配内容,如果找到一个则match对象,如果没有找到则返回None。
  函数语法如下:

re.search(pattern, string, flags=0)

  参数说明如下:

参数 参数说明
pattern 匹配的正则表达式
string 要匹配的字符串
flags 标志位,用于控制正则表达式的匹配方式,如是否区分大小写,多行匹配等

re.match()函数

  re.match()函数在输入字符串开始处查找匹配内容,如果找到一个则match对象,如果没有找到则返回None。
  函数语法如下:

re.match(pattern, string, flags=0)

  参数说明如下:

参数 参数说明
pattern 匹配的正则表达式
string 要匹配的字符串
flags 标志位,用于控制正则表达式的匹配方式,如是否区分大小写,多行匹配等

  下面我们简单讨论一下re.search()和re.match()的区别。
  re.match()只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;re.search()匹配整个字符串,直到找到一个匹配。
  re.search()和re.match()如果匹配成功都返回match对象。下面是match对象的一些常用方法:

方法 返回值
group() 返回匹配的子字符串
start() 返回子字符串的开始索引
end() 返回子字符串的结束索引
span() 返回子字符串的跨度,它是一个二元素的元组

re.findall()函数

  re.findall()函数在输入字符串中查找所有匹配内容,如果匹配成功,则返回match列表对象,如果匹配失败则返回None。
  函数语法如下:

re.findall(string[, pos[, endpos]])

  参数说明如下:

参数 参数说明
string 待匹配的字符串
pos 可选参数,指定字符串的起始位置,默认为0
endpos 可选参数,指定字符串的结束为止,默认为字符串的长度

re.finditer()函数

  re.finditer()函数在输入字符串中查找所有匹配内容,如果匹配成功,则返回容纳match的可迭代对象,通过迭代对象每次可以返回一个match对象,如果匹配失败则返回None。
  函数语法如下:

re.finditer(pattern, string, flags=0)

  参数说明如下:

参数 参数说明
pattern 匹配的正则表达式
string 要匹配的字符串
flags 标志位,用于控制正则表达式的匹配方式,如是否区分大小写,多行匹配等

re.split()函数

  re.split()函数按照匹配的字符串进行字符串分割,返回字符串列表对象。
  函数语法如下:

re.split(pattern, string[, maxsplit=0, flags=0])

  参数说明如下:

参数 参数说明
pattern 匹配的正则表达式
string 要匹配的字符串
maxsplit 分割次数,默认为0,不限制次数
flags 标志位,用于控制正则表达式的匹配方式,如是否区分大小写,多行匹配等

re.sub()函数

  re.sub()函数用于替换匹配的子字符串,返回替换之后的字符串。
  函数语法如下:

re.sub(pattern, repl, string, count=0, flags=0)

  参数说明如下:

参数 参数说明
patern 正则中的模式字符串
repl 替换的字符串,也可为一个函数
string 要被查找替换的原始字符串
count 模式匹配后替换的最大次数,默认为0,表示替换所有的匹配
flags 编译时用的匹配模式,数字形式

re.compile()函数

  re.compile()函数可以编译正则表达式。
  函数语法如下:

re.compile(pattern[, flags=0])

  参数说明如下:

参数 参数说明
pattern 一个字符串形式的正则表达式
flags 可选参数,表示匹配模式,如是否区分大小写,多行匹配等

  re.compile()函数返回一个编译的正则表达式对象regex。

正则表达式修饰符

修饰符 描述
re.I 使匹配对大小写不敏感
re.L 做本地化识别匹配
re.M 设置多行模式,多行匹配,影响^和$
re.S 使.匹配包括换行在内的所有字符
re.U 根据Unicode字符集解析字符,影响\w, \W, \b, \B
re.X 设置详细模式,详细模式下可以在正则表达式中添加注释, 可以有空格和换行
发布了21 篇原创文章 · 获赞 6 · 访问量 1656

猜你喜欢

转载自blog.csdn.net/qq_45554010/article/details/104022260