Python 正则表达式



正则表达式是一种特殊的字符序列,它使用专门的语法(包含在模式中)来帮助您匹配或查找其他字符串或字符串集。正则表达式通常称为 regex 或 regexp。

通常,此类模式由字符串搜索算法用于字符串的“查找”或“查找和替换”操作,或用于输入验证。

数据科学项目中大规模文本处理需要对文本数据进行操作。许多编程语言(包括 Python)都支持正则表达式处理。Python 的标准库为此目的提供了 **re** 模块。

由于 **re** 模块中定义的大多数函数都使用原始字符串,因此让我们首先了解什么是原始字符串。

原始字符串

正则表达式使用反斜杠字符 ('\') 来表示特殊形式,或允许使用特殊字符而不调用它们的特殊含义。另一方面,Python 使用相同的字符作为转义字符。因此,Python 使用原始字符串表示法。

如果在引号符号之前用 r 或 R 作前缀,则字符串变为原始字符串。因此,'Hello' 是普通字符串,而 r'Hello' 是原始字符串。

>>> normal="Hello"
>>> print (normal)
Hello
>>> raw=r"Hello"
>>> print (raw)
Hello

在正常情况下,两者之间没有区别。但是,当转义字符嵌入到字符串中时,普通字符串实际上会解释转义序列,而原始字符串不会处理转义字符。

>>> normal="Hello\nWorld"
>>> print (normal)
Hello
World
>>> raw=r"Hello\nWorld"
>>> print (raw)
Hello\nWorld

在上面的示例中,当打印普通字符串时,转义字符 '\n' 会被处理以引入换行符。但是,由于原始字符串运算符 'r',转义字符的效果不会根据其含义进行转换。

元字符

大多数字母和字符只会匹配自身。但是,某些字符是特殊的元字符,并且不匹配自身。元字符是具有特殊含义的字符,类似于通配符中的 *。

以下是元字符的完整列表:

. ^ $ * + ? { } [ ] \ | ( )

方括号符号 [ 和 ] 表示您希望匹配的一组字符。字符可以单独列出,也可以作为字符范围列出,用 '-' 分隔。

序号 元字符及描述
1

[abc]

匹配字符 a、b 或 c 中的任何一个
2

[a-c]

使用范围表示相同的字符集。
3

[a-z]

仅匹配小写字母。
4

[0-9]

仅匹配数字。
5

'^'

补充 [] 中的字符集。[^5] 将匹配除 '5' 之外的任何字符。

'\' 是一个转义元字符。当它后面跟着各种字符时,它会形成各种特殊的序列。如果您需要匹配 [ 或 \,您可以用反斜杠在前面加上它们来消除它们的特殊含义:\[ 或 \\。

以下列出了以 '\' 开头的此类特殊序列表示的预定义字符集:

序号 元字符及描述
1

\d

匹配任何十进制数字;这等效于类 [0-9]。
2

\D

匹配任何非数字字符;这等效于类 [^0-9]。
3 **\s**匹配任何空白字符;这等效于类 [\t\n\r\f\v]。
4

\S

匹配任何非空白字符;这等效于类 [^\t\n\r\f\v]。
5

\w

匹配任何字母数字字符;这等效于类 [a-zA-Z0-9_]。
6

\W

匹配任何非字母数字字符。等效于类 [^a-zA-Z0-9_]。
7

.

匹配除换行符 '\n' 之外的任何单个字符。
8

?

匹配其左侧模式的 0 次或 1 次出现
9

+

其左侧模式的 1 次或多次出现
10

*

其左侧模式的 0 次或多次出现
11

\b

单词和非单词之间的边界,/B 与 /b 相反
12

[..]

匹配方括号中任意单个字符,[^..] 匹配方括号中不存在的任意单个字符。
13

\

用于特殊含义的字符,例如 \. 匹配句点,\+ 匹配加号。
14

{n,m}

匹配前面表达式的至少 n 次,至多 m 次出现。
15

a| b

匹配 a 或 b。

Python 的 re 模块提供了许多有用的函数,用于查找匹配项、搜索模式以及用其他字符串替换匹配的字符串等。

re.match() 函数

此函数尝试使用可选的 flagsstring 的开头匹配 RE pattern。以下是此函数的语法

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

以下是参数的描述:

序号 参数 & 描述
1

pattern

要匹配的正则表达式。

2

String

要搜索的字符串,将在字符串开头匹配模式。

3

Flags

可以使用按位或 (|) 指定不同的标志。这些是修饰符,如下表所示。

re.match() 函数成功时返回一个match 对象,失败时返回None。match 对象实例包含有关匹配的信息:它从哪里开始和结束,它匹配的子字符串等。

match 对象的 start() 方法返回模式在字符串中的起始位置,end() 返回结束位置。

如果找不到模式,则 match 对象为 None。

我们使用match 对象的group(num)groups() 函数来获取匹配的表达式。

序号 Match 对象方法 & 描述
1 group(num=0) 此方法返回整个匹配项(或特定子组 num)
2 groups() 此方法以元组的形式返回所有匹配的子组(如果没有,则为空)

示例

import re
line = "Cats are smarter than dogs"
matchObj = re.match( r'Cats', line)
print (matchObj.start(), matchObj.end())
print ("matchObj.group() : ", matchObj.group())

它将产生以下输出

0 4
matchObj.group() : Cats

re.search() 函数

此函数使用可选的 flagsstring 中搜索 RE pattern 的第一次出现。以下是此函数的语法

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

以下是参数的描述:

序号 参数 & 描述
1

Pattern

要匹配的正则表达式。

2

String

要搜索的字符串,将在字符串中的任何位置匹配模式。

3

Flags

可以使用按位或 (|) 指定不同的标志。这些是修饰符,如下表所示。

re.search 函数成功时返回一个match 对象,失败时返回none。我们使用match 对象的group(num)groups() 函数来获取匹配的表达式。

序号 Match 对象方法 & 描述
1 group(num=0) 此方法返回整个匹配项(或特定子组 num)
2 groups() 此方法以元组的形式返回所有匹配的子组(如果没有,则为空)

示例

import re
line = "Cats are smarter than dogs"
matchObj = re.search( r'than', line)
print (matchObj.start(), matchObj.end())
print ("matchObj.group() : ", matchObj.group())

它将产生以下输出

17 21
matchObj.group() : than

匹配与搜索

Python 提供了两种基于正则表达式的不同基本操作,match 仅检查字符串开头的匹配项,而search 检查字符串中任何位置的匹配项(这是 Perl 默认执行的操作)。

示例

import re
line = "Cats are smarter than dogs";
matchObj = re.match( r'dogs', line, re.M|re.I)
if matchObj:
   print ("match --> matchObj.group() : ", matchObj.group())
else:
   print ("No match!!")
searchObj = re.search( r'dogs', line, re.M|re.I)
if searchObj:
   print ("search --> searchObj.group() : ", searchObj.group())
else:
   print ("Nothing found!!")

执行上述代码后,将产生以下输出

No match!!
search --> matchObj.group() : dogs

re.findall() 函数

findall() 函数以字符串或元组列表的形式返回字符串中模式的所有不重叠匹配项。字符串从左到右扫描,并按找到的顺序返回匹配项。结果中包含空匹配项。

语法

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

参数

序号 参数 & 描述
1

Pattern

要匹配的正则表达式。

2

String

要搜索的字符串,将在字符串中的任何位置匹配模式。

3

Flags

可以使用按位或 (|) 指定不同的标志。这些是修饰符,如下表所示。

示例

import re
string="Simple is better than complex."
obj=re.findall(r"ple", string)
print (obj)

它将产生以下输出

['ple', 'ple']

以下代码在 findall() 函数的帮助下获取句子中的单词列表。

import re
string="Simple is better than complex."
obj=re.findall(r"\w*", string)
print (obj)

它将产生以下输出

['Simple', '', 'is', '', 'better', '', 'than', '', 'complex', '', '']

re.sub() 函数

使用正则表达式的最重要的re 方法之一是sub

语法

re.sub(pattern, repl, string, max=0)

此方法将 string 中 RE pattern 的所有出现替换为 repl,除非提供了 max,否则将替换所有出现。此方法返回修改后的字符串。

示例

import re
phone = "2004-959-559 # This is Phone Number"

# Delete Python-style comments
num = re.sub(r'#.*$', "", phone)
print ("Phone Num : ", num)

# Remove anything other than digits
num = re.sub(r'\D', "", phone)
print ("Phone Num : ", num)

它将产生以下输出

Phone Num : 2004-959-559
Phone Num : 2004959559

示例

以下示例使用 sub() 函数替换所有出现的 is 为 was 单词:

import re
string="Simple is better than complex. Complex is better than complicated."
obj=re.sub(r'is', r'was',string)
print (obj)

它将产生以下输出

Simple was better than complex. Complex was better than complicated.

re.compile() 函数

compile() 函数将正则表达式模式编译成正则表达式对象,可以使用其 match()、search() 及其他方法进行匹配。

语法

re.compile(pattern, flags=0)

Flags

序号 修饰符 & 描述
1

re.I

执行不区分大小写的匹配。

2

re.L

根据当前区域设置解释单词。此解释会影响字母组(\w 和 \W),以及单词边界行为(\b 和 \B)。

3

re.

M 使 $ 匹配行尾(不仅仅是字符串的结尾),并使 ^ 匹配任何行的开头(不仅仅是字符串的开头)。

4

re.S

使句点 (.) 匹配任何字符,包括换行符。

5

re.U

根据 Unicode 字符集解释字母。此标志会影响 \w、\W、\b、\B 的行为。

6

re.X

允许使用“更简洁”的正则表达式语法。它忽略空格(集合 [] 内除外,或被反斜杠转义时除外),并将未转义的 # 视为注释标记。

序列:

prog = re.compile(pattern)
result = prog.match(string)

等效于:

result = re.match(pattern, string)

但是,当在一个程序中多次使用表达式时,使用 re.compile() 并保存生成的正则表达式对象以供重用效率更高。

示例

import re
string="Simple is better than complex. Complex is better than complicated."
pattern=re.compile(r'is')
obj=pattern.match(string)
obj=pattern.search(string)
print (obj.start(), obj.end())

obj=pattern.findall(string)
print (obj)

obj=pattern.sub(r'was', string)
print (obj)

它将产生以下输出:

7 9
['is', 'is']
Simple was better than complex. Complex was better than complicated.

re.finditer() 函数

此函数返回一个迭代器,对字符串中 RE 模式的所有不重叠匹配项生成匹配对象。

语法

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

示例

import re
string="Simple is better than complex. Complex is better than complicated."
pattern=re.compile(r'is')
iterator = pattern.finditer(string)
print (iterator )

for match in iterator:
   print(match.span())

它将产生以下输出

(7, 9)
(39, 41)

Python 正则表达式的用例

查找所有副词

findall() 匹配模式的所有出现,而不仅仅是 search() 的第一个出现。例如,如果作者想要查找某些文本中的所有副词,他们可能会以如下方式使用 findall():

import re
text = "He was carefully disguised but captured quickly by police."
obj = re.findall(r"\w+ly\b", text)
print (obj)

它将产生以下输出

['carefully', 'quickly']

查找以元音开头的单词

import re
text = 'Errors should never pass silently. Unless explicitly silenced.'
obj=re.findall(r'\b[aeiouAEIOU]\w+', text)
print (obj)

它将产生以下输出

['Errors', 'Unless', 'explicitly']

正则表达式修饰符:选项标志

正则表达式文字可以包含一个可选的修饰符来控制匹配的各个方面。修饰符指定为可选标志。您可以使用异或 (|) 提供多个修饰符,如前面所示,并且可以使用以下其中一个表示:

序号 修饰符 & 描述
1

re.I

执行不区分大小写的匹配。

2

re.L

根据当前区域设置解释单词。此解释会影响字母组(\w 和 \W),以及单词边界行为(\b 和 \B)。

3

re.M

使 $ 匹配行尾(不仅仅是字符串的结尾),并使 ^ 匹配任何行的开头(不仅仅是字符串的开头)。

4

re.S

使句点 (.) 匹配任何字符,包括换行符。

5

re.U

根据 Unicode 字符集解释字母。此标志会影响 \w、\W、\b、\B 的行为。

6

re.X

允许使用“更简洁”的正则表达式语法。它忽略空格(集合 [] 内除外,或被反斜杠转义时除外),并将未转义的 # 视为注释标记。

正则表达式模式

除控制字符(+ ? . * ^ $ ( ) [ ] { } | \) 外,所有字符都与其自身匹配。您可以通过在控制字符前面加上反斜杠来转义它。

下表列出了 Python 中可用的正则表达式语法:

序号 模式 & 描述
1

^

匹配行首。

2

$

匹配行尾。

3

.

匹配除换行符外的任何单个字符。使用 m 选项允许它匹配换行符。

4

[...]

匹配括号中的任何单个字符。

5

[^...]

匹配括号中不存在的任何单个字符

6

re*

匹配前面表达式的 0 次或多次出现。

7

re+

匹配前面表达式的 1 次或多次出现。

8

re?

匹配前面表达式的 0 次或 1 次出现。

9

re{ n}

精确匹配前面表达式 n 次出现。

10

re{ n,}

匹配前面表达式的 n 次或多次出现。

11

re{ n, m}

匹配前面表达式的至少 n 次,至多 m 次出现。

12

a| b

匹配 a 或 b。

13

(re)

分组正则表达式并记住匹配的文本。

14

(?imx)

临时启用正则表达式中的 i、m 或 x 选项。如果在括号内,则仅影响该区域。

15

(?-imx)

临时禁用正则表达式中的 i、m 或 x 选项。如果在括号内,则仅影响该区域。

16

(?: re)

分组正则表达式而不记住匹配的文本。

17

(?imx: re)

临时启用括号内的 i、m 或 x 选项。

18

(?-imx: re)

临时禁用括号内的 i、m 或 x 选项。

19

(?#...)

注释。

20

(?= re)

使用模式指定位置。没有范围。

21

(?! re)

使用模式否定指定位置。没有范围。

22

(?> re)

匹配不回溯的独立模式。

23

\w

匹配单词字符。

24

\W

匹配非单词字符。

25

\s

匹配空格。等效于 [\t\n\r\f]。

26

\S

匹配非空格。

27

\d

匹配数字。等效于 [0-9]。

28

\D

匹配非数字。

29

\A

匹配字符串开头。

30

\Z

匹配字符串结尾。如果存在换行符,则匹配换行符之前的字符。

31

\z

匹配字符串结尾。

32

\G

匹配上次匹配结束的位置。

33

\b

在括号外匹配单词边界。在括号内匹配退格键 (0x08)。

34

\B

匹配非单词边界。

35

\n, \t, etc.

匹配换行符、回车符、制表符等。

36

\1...\9

匹配第 n 个分组子表达式。

37

\10

如果第 n 个分组子表达式已匹配,则匹配它。否则引用字符代码的八进制表示。

正则表达式示例

字面字符

序号 示例 & 描述
1

python

匹配 "python"。

字符类

序号 示例 & 描述
1

[Pp]ython

匹配 "Python" 或 "python"

2

rub[ye]

匹配 "ruby" 或 "rube"

3

[aeiou]

匹配任何一个小写元音

4

[0-9]

匹配任何数字;与 [0123456789] 相同

5

[a-z]

匹配任何小写 ASCII 字母

6

[A-Z]

匹配任何大写 ASCII 字母

7

[a-zA-Z0-9]

匹配以上任何一个

8

[^aeiou]

匹配除小写元音以外的任何字符

9

[^0-9]

匹配除数字以外的任何字符

特殊字符类

序号 示例 & 描述
1

.

匹配除换行符以外的任何字符

2

\d

匹配数字:[0-9]

3

\D

匹配非数字:[^0-9]

4

\s

匹配空格字符:[ \t\r\n\f]

5

\S

匹配非空格:[^ \t\r\n\f]

6

\w

匹配单个单词字符:[A-Za-z0-9_]

7

\W

匹配非单词字符:[^A-Za-z0-9_]

重复情况

序号 示例 & 描述
1

ruby?

匹配 "rub" 或 "ruby":y 是可选的

2

ruby*

匹配 "rub" 加 0 个或多个 y

3

ruby+

匹配 "rub" 加 1 个或多个 y

4

\d{3}

精确匹配 3 位数字

5

\d{3,}

匹配 3 位或更多位数字

6

\d{3,5}

匹配 3、4 或 5 位数字

非贪婪重复

这匹配最少的重复次数:

序号 示例 & 描述
1

<.*>

贪婪重复:匹配 "<python>perl>"

2

<.*?>

非贪婪:在 "<python>perl>" 中匹配 "<python>"

使用括号分组

序号 示例 & 描述
1

\D\d+

无分组:+ 重复 \d

2

(\D\d)+

分组:+ 重复 \D\d 对

3

([Pp]ython(, )?)+

匹配 "Python"、"Python, python, python" 等。

反向引用

这将再次匹配先前匹配的组:

序号 示例 & 描述
1

([Pp])ython\1ails

匹配 python&pails 或 Python&Pails

2

(['"])[^\1]*\1

单引号或双引号字符串。\1 匹配第一个组匹配的任何内容。\2 匹配第二个组匹配的任何内容,依此类推。

备选方案

序号 示例 & 描述
1

python|perl

匹配 "python" 或 "perl"

2

rub(y|le)

匹配 "ruby" 或 "ruble"

3

Python(!+|\?)

"Python" 后跟一个或多个 ! 或一个 ?

锚点

这需要指定匹配位置。

序号 示例 & 描述
1

^Python

匹配字符串或内部行开头的 "Python"

2

Python$

匹配字符串或行结尾的 "Python"

3

\APython

匹配字符串开头的 "Python"

4

Python\Z

匹配字符串结尾的 "Python"

5

\bPython\b

匹配单词边界处的 "Python"

6

\brub\B

\B 是非单词边界:匹配 "rube" 和 "ruby" 中的 "rub",但不是单独的 "rub"

7

Python(?=!)

如果后面跟着感叹号,则匹配 "Python"。

8

Python(?!!)

如果后面不跟着感叹号,则匹配 "Python"。

带括号的特殊语法

序号 示例 & 描述
1

R(?#comment)

匹配 "R"。其余都是注释

2

R(?i)uby

匹配 "uby" 时不区分大小写

3

R(?i:uby)

与上面相同

4

rub(?:y|le)

仅分组,不创建 \1 反向引用

广告
© . All rights reserved.