Posts Python正则表达式
Post
Cancel

Python正则表达式

一、 前言

正则表达式在文本模式匹配的过程中, 是非常强大也是非常常用的工具

本文将简要介绍: 在Python中如何使用正则表达式进行匹配, 关于正则表达式的数学知识不再赘述

在正篇开始之前, 不要忘记字符串有原生的一些匹配函数, 如str.find()str.endwith()str.endwith(), 有时我们并不需要正则表达式那么强大的功能—-我们应该尽量选用轻量级的实现以减少开销

二、 正篇

导入模块:

1
import re 

2.1 match()

match()有两种用法, 但无论哪种方法, 都实现一个功能: 在字符串开头匹配一次正则表达式

举几个例子, 对于\d+/\d+/这样的正则表达式, 有以下情况:

1
2
3
4
123/456/		-> 成功, 匹配到'123/456'
123/456/ajxo	-> 成功, 匹配到'123/456'
123/456/789/234	-> 成功, 匹配到'123/456'
/123/456/		-> 失败, 在开头处匹配失败

下面是match()的两种用法:

2.1.1 传入两个字符串直接匹配

这种方法的形式是re.match(regular_expression:str, source:str) -> bool

查看示例:

1
2
3
4
5
6
7
8
9
10
11
12
import re

regx = r'\d+/\d+/'

string = '123/456/34'

if re.match(regx, string):
    result = 'matched'
else:
    result = 'not matched'

print(result)

注意: 正则表达式的字符串包含转义符, 使用时务必注意转义, 如在字符串前加’r’

2.1.2 预编译正则表达式后匹配

这种方法先使用re.compile()对正则表达式进行编译, 生成一个对应的模式对象, 再使用这个模式对象进行匹配

查看示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
import re

regx = re.compile(r'\d+/\d+/')

string = '123/456/34'

print(type(regx))

if regx.match(string):
    result = 'matched'
else:
    result = 'not matched'
print(result)

2.1.3 match()的返回值

实践出真知:

1
print(type(re.match(regx, string)))
  • 匹配成功时, 返回<class '_sre.SRE_Match'>
  • 匹配失败时, 返回<class 'NoneType'>

直接打印这个对象试试:

1
2
3
match_ret = match(regx, string)

print(match_ret)

得到的结果是

1
<_sre.SRE_Match object; span=(0, 8), match='123/456/'>

可以看到核心的两个成员变量是spanmatch

  • span是匹配到的范围
  • match是匹配到的字符串

我们可以用其span()方法得到span、 访问string以得到match:

1
2
print(match_ret.span())
print(match_ret.string)

得到的结果是:

1
2
(0, 8)
123/456/34

2.2 findall()

可以说是match()的加强版, 它的作用是找出字符串中所有的匹配

注意: 在findall()下, 一个子串不能同时在两个个匹配结果中:

1
2
string = '123/456/34/2/1'
match_ret = regx.findall(string)

这样得到的匹配结果只有两个:'123/456/''34/2/'

findall()match()的返回值大有不同—-findall()将匹配结果以列表的形式返回

承接上文的例子, 输出返回值, 结果为

1
['123/456/', '34/2/']

如果匹配失败, 则返回空列表, 由于空列表在条件语句中可以当做False使用, 所以findall()也可以很便利地用于条件语句

2.3 捕获组

使用括号进行正则表达式匹配的分组, 也是python的前辈—-java的传统艺能了

我们使用括号, 对正则表达式的个别部分进行”标志”, 以在匹配完毕后使用group()捕获这些特定的部分

2.3.1 match()捕获组

对于match(), 我们需要通过返回值的group()方法捕获

查看示例:

1
2
3
4
5
6
7
8
9
10
import re

regx = re.compile(r'(\d+)/(\d+)/')

string = '123/456/'
match_ret = regx.match(string)

print(match_ret.group(0))
print(match_ret.group(1))
print(match_ret.group(2))

结果为:

1
2
3
123/456/
123
456

注意: group(0)返回的是整体的匹配结果, 这可能与我们的猜想不一样

2.3.2 findall()捕获组

对于findall(), 在分组匹配后, 其返回值发生了变化: 列表中的元素变为字符串的元组

查看示例:

1
2
3
4
5
6
7
8
9
import re

regx = re.compile(r'(\d+)/(\d+)/')

string = '123/456/789/321/'

match_ret = regx.findall(string)

print(match_ret)

结果为:

1
[('123', '456'), ('789', '321')]

把字符串变为元组的目的, 就是为了体现分组的效果

2.4 Python支持的正则表达式元字符和语法

regular-expression-supported-by-python

数量词的贪婪模式与非贪婪模式

正则表达式通常用于在文本中查找匹配的字符串。Python里数量词默认是贪婪的(在少数语言里也可能是默认非贪婪),总是尝试匹配尽可能多的字符;非贪婪的则相反,总是尝试匹配尽可能少的字符。例如:正则表达式”ab*“如果用于查找”abbbc”,将找到”abbb”。而如果使用非贪婪的数量词”ab*?”,将找到”a”。

三、 参考资料

This post is licensed under CC BY 4.0 by the author.