Python 正则表达式

本文介绍了 Python 中的正则表达式的基础知识,通过示例讲述了如何利用 re 模块使用正则表达式处理文本。

正则表达式创建了一种字符序列的模式,可以匹配很多符合此模式的字符串,比如 .* 可以匹配到任意数量的任意字符串。正则表达式很适合用来处理文本。

正则表达式模块

Python 内置了 re 模块用于处理正则表达式。

要使用正则表达式,请先导入 re 模块:

import re

Python 中的正则表达式

导入 re 模块后,您可以开始使用正则表达式:

搜索字符串以查看它是否以“The”开头并以“Spain”结尾:

import re

txt = "The rain in Spain"
x = re.search("^The.*Spain$", txt)

正则表达式函数

re 模块提供了一组函数,允许我们在字符串中搜索匹配项:

Function Description
findall 返回包含所有匹配项的列表
search 扫描整个字符串寻找第一个匹配的位置, 并返回一个匹配的 Match 对象。
split 用指定的 pattern 分割字符串,返回分割后的字符串列表
sub 替换指定模式的字符串

正则表达式模式

正则表达式使用一些特定的字符组成一些模式进行文本匹配。

元字符

元字符是具有特殊含义的字符:

字符 说明 示例
[] 表示一个字符集合 [a-m]
\ 转义字符 \d
. 匹配除换行外的任意字符 he..o
^ 匹配行开头 ^hello
$ 匹配行结尾 world$
* 0 次或者多次 aix*
+ 1 次或者多次 aix+
{} 指定的次数 al{2}
| 或者 falls&stays
() 分组

预定义字符

\ 和一个字符组成的特殊序列具有特殊的含义,在下表列出。

Character Description Example
\A 匹配字符串的开头 "\AThe"
\b 匹配单词的边界 (如果字符串前面有个 “r” 则字符串被视为原始字符串) r"\bain"r"ain\b"
\B 匹配非单词的边界 (如果字符串前面有个 “r” 则字符串被视为原始字符串) r"\Bain"r"ain\B"
\d 匹配一个数字,相当于 [0-9] "\d"
\D 匹配一个非数字,相当于 [^0-9] "\D"
\s 匹配空格 "\s"
\S 匹配非空格 "\S"
\w 匹配一个单词的字符 [a-zA-Z0-9_] "\w"
\W 匹配一个非单子的字符,相当于 [^a-zA-Z0-9_] "\W"
\Z 只匹配字符串结束 "Spain\Z"

如果 \ 后跟的字符不是 ASCII 数位或者 ASCII 字母,那么正则样式将匹配第二个字符。比如,\$ 匹配字符 '$'.

集合

[] 表示一个字符集合,可以匹配到集合中的任意一个字符。

Set Description
[arn] 匹配 arn)
[a-n] 匹配 an 之间的字母
[^arn] 匹配 a, r, 和 n 之外的所有字符
[0123] 匹配 0123
[0-9] 匹配 09 之间的数字
[0-5][0-9] 匹配 0059 的所有
[a-zA-Z] 匹配大写或者小写的所有字母
[+] 匹配 + 字符。在集合中 +, *, ., |, (), $,{} 没有特殊含义

findall() 函数

findall() 函数返回一个包含所有匹配项的列表。findall() 函数接受 2 个参数:

  • pattern: 要查找的正则表达式模式
  • string: 被查找的文本

打印所有匹配项的列表:

import re

txt = "The rain in Spain"
x = re.findall("ai", txt)
print(x) # ['ai', 'ai']

findall() 函数按照匹配的顺序返回列表,如果未找到匹配项,则返回一个空列表:

import re

txt = "The rain in Spain"
x = re.findall("Portugal", txt)
print(x) # []

split() 函数

split() 函数使用指定的正则表达式去分割一个字符串,将分割后的子串作为列表返回。split() 函数需要 2 个参数:

  • pattern: 作为分割项的正则表达式模式
  • string: 被分割的文本
  • maxsplit: 最大分割数量

使用空白字符分割字符串:

import re

txt = "The rain in Spain"
x = re.split("\s", txt)
print(x) # ['The', 'rain', 'in', 'Spain']

还可以通过 maxsplit 参数来控制分割数量。下面例子仅分割 2 次:

import re

txt = "The rain in Spain"
x = re.split("\s", txt, 1)
print(x) # ['The', 'rain in Spain']

sub() 函数

sub() 函数用指定的文本替换匹配项。sub() 函数至少需要 3 个参数:

  • pattern: 搜索匹配项的正则模式,搜索到的内容会被 repl 参数指定的内容替换
  • repl: 替换文本内容
  • string: 被处理的文本
  • count:

用数字 9 替换每个空白字符:

import re

txt = "The rain in Spain"
x = re.sub("\s", "9", txt)
print(x) # The9rain9in9Spain

您可以通过指定 count 参数来控制替换次数 :

替换前 2 次出现:

import re

txt = "The rain in Spain"
x = re.sub("\s", "9", txt, 2)
print(x) # The9rain9in Spain

search() 函数

search() 函数在字符串中搜索匹配项,如果有匹配项返回一个 Match 对象,如果未找到匹配项,返回 Nonesearch() 函数只返回第一个匹配项的 Match 对象。

search() 函数需要 2 个参数:

  • pattern: 要搜索的正则表达式模式
  • string: 被搜索的文本

搜索字符串中的第一个空白字符:

import re

txt = "The rain in Spain"
x = re.search("\s", txt)

print("The first white-space character is located in position:", x.start())

进行不返回匹配项的搜索:

import re

txt = "The rain in Spain"
x = re.search("Portugal", txt)
print(x)

Match 对象

search() 函数会在找到匹配项的时候返回一个 Match 对象。Match 对象是包含有关搜索结果信息的对象。

执行将返回 Match 对象的搜索:

import re

txt = "The rain in Spain"
x = re.search("ai", txt)
print(x) # <re.Match object; span=(5, 7), match='ai'>
print(type(x)) # <class 're.Match'>

Match 对象具有用于检索有关搜索和结果的信息的属性和方法:

.span() 返回一个包含匹配开始和结束位置的元组。 .string 返回传递给函数的字符串 .group() 返回字符串中匹配的部分

打印第一个匹配项的位置(开始和结束位置)。

正则表达式查找任何以大写“S”开头的单词:

import re

txt = "The rain in Spain"
x = re.search(r"\bS\w+", txt)
print(x.span()) # (12, 17)
print(x.string) # The rain in Spain
print(x.group()) # Spain

**注意:**如果没有匹配,返回 None 值,而不是 Match 对象。