Python正则表达式re模块详解:从入门到精通掌握字符匹配技巧

[id_18752[id_[id_1593872924]7498159]896]

Python正则表达式re模块详解:从入门到精通掌握字符匹配技巧

正则表达式本身是一种小型且高度专业化的编程语言。在 Python 中,通过内嵌集成 re 模块,程序媛们能够直接调用该模块来实现正则匹配。正则表达式模式会被编译成一系列字节码,接着由用 C 编写的匹配引擎来执行。

二、正则表达式中常用的字符含义

1、普通字符和11个元字符:

普通字符

匹配自身

abc

abc

匹配除换行符"\n"之外的任意字符,并且在 DOTALL 模式下也能匹配换行符。

a.c

abc

转义字符,使后一个字符改变原来的意思

a\.c;a\\c

a.c;a\c

匹配前一个字符0或多次

abc*

ab;abccc

匹配前一个字符1次或无限次

abc+

abc;abccc

[id_1160689407]

ab;abc

匹配字符串开头。在多行模式中匹配每一行的开头

^abc

abc

匹配字符串末尾,在多行模式中匹配每一行的末尾

abc$

abc

匹配左右表达式中的任意一个,从左至右进行匹配。如果某个元素没有被包含在括号中,那么它的范围就是整个正则表达式。

abc|def

abc

def

{}

{m}表示匹配前一个字符 m 次,{m,n}表示匹配前一个字符 m 至 n 次,若未给出 n ,则匹配 m 至无限次。

ab{1,2}c

abc

abbc

[]

字符集。其对应的位置能够是字符集中的任意字符。字符集中的字符既可以逐个进行罗列,也可以给出范围,例如[abc]或者[a - c]。而[^abc]表示取反,也就是非 abc。

所有特殊字符在字符集中都不再具有其原本的特殊含义。通过使用\反斜杠进行转义操作,能够使特殊字符恢复其特殊含义。

a[bcd]e

abe

ace

ade

()

分组将被括起来,从表达式的左边开始,每当没遇到一个分组的左括号“(”时,编号就会加 1.

分组表达式可作为一个整体,其后可接数量词。在表达式中,|仅在该组内有效。

(abc){2}

a(123|456)c

abcabc

a456c

这里需要强调一下反斜杠\的作用:

使用 re 模块的 search 方法在字符串'tinafeihahafei tinafeihahatina'中搜索模式'(tina)(fei)haha\2',找到匹配的内容后,通过 group 方法获取匹配的结果,最终结果赋值给变量 a 。
print(a)
结果:
tinafeihahafei

2、预定义字符集(可以写在字符集[...]中)

\d

数字:[0-9]

a\bc

a1c

\D

非数字:[^\d]

a\Dc

abc

\s

匹配任何空白字符:[\t\r\n\f\v]

a\sc

a c

\S

非空白字符:[^\s]

a\Sc

abc

\w

匹配包括下划线在内的任何字字符:[A-Za-z0-9_]

a\wc

abc

\W

匹配非字母字符,即匹配特殊字符

a\Wc

a c

\A

仅匹配字符串开头,同^

\Aabc

abc

\Z

仅匹配字符串结尾,同$

abc\Z

abc

\b

在\w和\W之间进行匹配,这意味着匹配单词边界。单词边界指的是单词与空格之间的位置。例如,“er\b”能够匹配“never”中的“er”,然而却不能匹配“verb”中的“er”。

\babc\b

a\b!bc

空格abc空格

a!bc

\B

[^\b]

a\Bbc

abc

这里需要强调一下\b的单词边界的理解:
w 等于从“tian tinaaaa”中找出所有包含“tina”的内容。
print(w)
在字符串“tian tinaaaa”中,使用 re.findall 函数去查找所有包含“tina”的部分,结果存储在变量 s 中。
print(s)
v 从 'tian#tinaaaa' 中找出所有包含 'tina' 的内容。
print(v)
使用正则表达式 r'\btina\b' 在字符串 'tian#tina@aaa' 中进行查找,找到的结果赋值给变量 a ,即 a 等于在该字符串中找到的所有匹配 'tina' 的部分。
print(a)
执行结果如下:
[]
['tina']
['tina']
['tina']

3、特殊分组用法:

分组,除了原有的编号外再指定一个额外的别名

(?Pabc){2}

abcabc

(?P=name)

引用别名为的分组匹配到字符串

(?P\d)abc(?P=id)

1abc1

5abc5

引用编号为的分组匹配到字符串

(\d)abc\1

1abc1

5abc5

三、re模块中常用功能函数

1、compile()

编译正则表达式模式,会返回一个对象的模式。可以将常用的正则表达式编译为正则表达式对象,以此能提高一定的效率。

格式:

re.compile(pattern,flags=0)

pattern: 编译时用的表达式字符串。

flags 是编译标志位,它可用来修改正则表达式的匹配方式,例如是否区分大小写以及多行匹配等。常用的 flags 包含:

标志

含义

re.S(DOTALL)

使.匹配包括换行在内的所有字符

re.I(IGNORECASE)

使匹配对大小写不敏感

re.L(LOCALE)

做本地化识别(locale-aware)匹配,法语等

re.M(MULTILINE)

多行匹配,影响^和$

re.X(VERBOSE)

该标志通过给予更灵活的格式以便将正则表达式写得更易于理解

re.U

从 Unicode 字符集来对字符进行解析,此标志会对\w、\W、\b、\B 产生影响。

import re
rr 是通过 re.compile 函数编译得到的,编译的内容是 '\\w*oo\\w*' 。
查找包含“oo”的单词,通过 rr.findall(tt) 来实现
执行结果如下:
“good”和“cool”

2、match()

决定 RE 是否在字符串的起始位置进行匹配。此方法并非完全匹配,当 pattern 结束而 string 还有剩余字符时,仍视为成功。若要完全匹配,可在表达式末尾添加边界匹配符“$”。

格式:

使用 re.match 函数,传入 pattern 和 string 作为参数,同时可以设置 flags 为 0 来进行匹配操作。

最终打印出匹配到的内容
使用 re.match 函数来匹配字符串 'Comwww.runcomoob' 中是否包含 'com' ,忽略大小写(re.I),然后获取匹配到的内容并输出。具体来说,就是在给定的字符串中查找以 'com' 开头的部分,并将其作为匹配结果输出。如果没有找到匹配的内容,则返回 None。
执行结果如下:
com
com

3、search()

格式:

在字符串 string 中搜索模式 pattern ,标志位 flags 为 0 。 它用于查找字符串中与给定模式匹配的部分。 该函数会返回一个匹配对象,如果没有找到匹配项,则返回 None 。 可以通过匹配对象的方法来获取关于匹配的详细信息。 例如,使用 group() 方法可以获取匹配的文本。

re.search 函数会在字符串内进行查找模式匹配的操作。它只要找到第一个匹配就会返回。如果字符串没有匹配的情况,就会返回 None。

最后输出匹配到的内容。
执行结果如下:
4com

match 和 search 一旦匹配成功,就会形成一个 match object 对象,这个 match object 对象具备以下这些方法:

a. group()返回re整体匹配的字符串,

group 函数,其参数为 n 和 m,该函数会返回组号为 n 且 m 所匹配的字符串。倘若组号不存在,就会抛出 indexError 异常。

groups()方法会返回一个包含正则表达式中所有小组字符串的元组,其范围是从 1 到所包含的小组号。通常情况下,groups()不需要参数,它会返回一个元组,该元组中的元素就是正则表达式中定义的组。

import re
a = "123abc456"
如果在字符串 a 中搜索到符合 "([0-9]*)([a-z]*)([0-9]*)" 模式的内容,那么就打印出通过 re.search 找到的匹配项的 group(0),即整体内容。例如对于 "123abc456" 这样的字符串,就会返回 "123abc456" 。
在字符串 a 中搜索符合 "([0-9]*)([a-z]*)([0-9]*)" 模式的内容,然后获取匹配到的第一个分组的内容,即数字部分。
使用正则表达式在字符串 a 中进行搜索,查找符合 "([0-9]*)([a-z]*)([0-9]*)" 模式的内容,然后获取匹配到的第二个分组的内容并打印出来,这里的第二个分组是由小写字母组成的部分,例如在字符串 "abc" 中,获取到的就是 "bc" 中的 "bc" 部分。
在 a 中搜索匹配 "([0-9]*)([a-z]*)([0-9]*)" 的模式,然后打印出匹配到的第三个分组,即数字部分,这里的数字部分是 456
###group(3) 列出第三个括号匹配的内容。###

4、findall()

re.findall 进行遍历匹配操作,能够获取到字符串里所有匹配的字符串,并且会返回一个列表。

格式:

在字符串 string 中查找与 pattern 匹配的所有子串,使用的标志为 flags=0 。

使用 re 模块的 compile 函数创建了一个正则表达式模式对象 p,该模式是 r'\d+',即匹配一个或多个数字。
使用 p 来查找符合 'o1n2m3k4' 的内容并进行打印。
执行结果如下:
有四个元素,分别是 '1'、'2'、'3'、'4'。

import re
tt = "Tina is a good girl, she is cool, clever, and so on..."
rr = re.compile(r'\w*oo\w*')
print(rr.findall(tt))
使用 re.findall 函数来查找字符串 tt 中所有包含 'oo' 的子串。其中,正则表达式 '(\w)*oo(\w)' 表示匹配任意数量的字母字符(包括空字符),接着是 'oo',最后再匹配任意一个字母字符。通过这种方式,可以找到 tt 中所有符合该模式的子串。
执行结果如下:
['good', 'cool']

5、finditer()

搜索 string 后,会返回一个迭代器,该迭代器可以顺序访问每一个匹配结果,这些匹配结果是 Match 对象。同时,它能找到 RE 匹配的所有子串,并将这些子串作为一个迭代器返回。

格式:

在字符串 string 中查找与 pattern 匹配的所有子串,使用的标志为 flags=0 ,通过 re.finditer 函数来实现。

iter 是在字符串 '12 drumm44ers drumming, 11... 10...' 中查找匹配正则表达式 '\d+' 的迭代器
for i in iter:
    print(i)
    print(i.group())
    print(i.span())
执行结果如下:
<_sre.SRE_Match object; span=(0, 2), match='12'>
12
(0, 2)
<_sre.SRE_Match object; span=(8, 10), match='44'>
44
(8, 10)
<_sre.SRE_Match object; span=(24, 26), match='11'>
11
(24, 26)
<_sre.SRE_Match object; span=(31, 33), match='10'>
10
(31, 33)

6、split()

按照能够匹配的子串将string分割后返回列表。

可以利用 re.split 来对字符串进行分割,例如:re.split(r'\s+', text);这样就能把字符串按照空格分割成一个单词的列表。

格式:

re 按照 pattern 对 string 进行分割操作,分割次数可以由 maxsplit 指定,如果不指定 maxsplit,则默认分割所有匹配的部分。

maxsplit用于指定最大分割次数,不指定将全部分割。

将分割后的结果打印出来
执行结果如下:
有 'one'、有 'two'、有 'three'、有 'four'、有 'five' 。

7、sub()

将 string 中每一个匹配的子串用 re 进行替换,然后返回替换后的字符串。

格式:

使用 re.sub 函数,传入 pattern、repl、string 和 count 参数,对 string 进行替换操作,pattern 是要匹配的模式,repl 是替换后的内容,count 是替换的次数(可选)。

import re
使用 re.sub 函数,将字符串 text 中的连续空白字符替换为“-”,然后打印替换后的结果。
执行结果如下:
JGood 是一个帅气的男孩,他很酷炫,很聪明,等等……

其中第二个函数是被替换后的字符串;在本例中这个字符串是'-'

第四个参数指替换个数。默认为0,表示每个匹配项都替换。

re.sub还允许使用函数对匹配项的替换进行复杂的处理。

使用 re.sub 函数,将字符串中的空格(r'\s')替换为 [空格内容],这里的空格内容是通过 lambda 函数 m 获取到的原始空格(m.group(0)),并将替换结果应用到指定的字符串 text 中,0 表示不进行全局替换,只进行第一次替换。

import re
text = "JGood is a handsome boy, he is cool, clever, and so on..."
使用 re.sub 函数,将字符串 text 中连续的空白字符(\s+)替换为 [原空白字符],并设置标志位为 0,最后打印替换后的结果。
执行结果如下:
JGood 是一个帅气的男孩,他很冷酷,很聪明,等等……

8、subn()

返回替换次数

格式:

subn 函数用于在字符串中进行模式匹配和替换操作。它接受模式(pattern)、替换内容(repl)、要处理的字符串(string)以及可选的计数参数(count,默认为 0)和标志参数(flags,默认为 0)。通过调用 subn 函数,可以在字符串中找到匹配指定模式的部分,并将其替换为指定的内容。函数返回一个包含替换后的字符串和实际替换的次数的元组。

使用 re.subn 函数,将字符串 '123456abcdef' 中所有的 '[1-2]' 替换为 'A',返回替换后的字符串以及替换的次数。具体为:先找到字符串中所有符合 '[1-2]' 模式的子串,然后将这些子串替换为 'A',最后返回替换后的字符串和替换的次数。
使用 re.sub 函数将字符串中的 "g.t" 替换为 "have",对字符串 'I get A,  I got B,I gut C' 进行操作。首先找到 "g.t" 这个模式,然后将其替换为 "have",最后返回替换后的字符串。
使用 re.subn 函数,将字符串中的 "g.t" 替换为 "have"。对字符串 'I get A,  I got B,I gut C' 进行替换操作,返回替换后的字符串以及替换的次数。
执行结果如下:
('AA3456abcdef', 2)
I have A,  I have B ,I have C
我拥有 A,我拥有 B,我拥有 C。

四、一些注意点

re.findall 的区别:它找到所有匹配的子串,并以列表形式返回。

re.match 只会去匹配字符串的起始部分。倘若字符串的起始部分与正则表达式不相符,那么匹配就会失败,此时函数会返回 None。re.search 则是会对整个字符串进行匹配,一直到找到一个匹配为止。

在字符串"abc33"中搜索包含数字的内容,通过 re.search 函数进行查找,找到后使用 group 方法获取匹配到的内容,最终将匹配到的内容赋值给变量 a,即 a 的值为"3"。
print(a)
使用 re.match 函数,传入模式 '[\d]' 和字符串 "abc33",将匹配结果赋值给变量 p 。
print(p)
使用 re.findall 函数在字符串 "abc33" 中查找所有的数字字符。通过正则表达式 '[\d]' 进行匹配,该正则表达式表示匹配任意一个数字。最终返回匹配到的数字字符列表,这里返回的是 ['3', '3']。
print(b)
执行结果:
3
None
['3', '3']

2、贪婪匹配与非贪婪匹配

前面的*、+、?等都属于贪婪匹配,意思是会尽可能地进行匹配。而后面加上?号后,就会使其变成惰性匹配。

使用 re.findall 函数在字符串 'a23b' 中查找所有匹配模式 "a(\d+?)" 的内容,将匹配到的结果存储在变量 a 中。
print(a)
b 是通过在字符串 'a23b' 中查找所有匹配模式 "a(\d+)" 的内容得到的。即从 'a23b' 中找出所有以 'a' 开头,后面跟着一个或多个数字的部分。
print(b)
执行结果:
['2']
['23']

a = re.match('<(.*)>','

title

').group() print(a) b = re.match('<(.*?)>','

title

').group() print(b) 执行结果:

title

使用 re 模块的 findall 函数来查找字符串 'a3333b' 中匹配模式 'a(\d+)b' 的内容,将匹配到的结果存储在变量 a 中。
print(a)
使用正则表达式 re 来查找字符串 'a3333b' 中符合模式 'a(\d+?)b' 的内容,将找到的结果赋值给变量 b 。
print(b)
执行结果如下:
['3333']
['3333']
#######################
这里需要注意的是,当前后均有限定条件时,就不存在贪婪模式了,并且非匹配模式会失效。

3、用flags时遇到的小坑

使用 re.split('a', '1A1a2A3', re.I) 进行分割,输出的结果未能区分大小写。
因为 re.split(pattern,string,maxsplit,flags) 默认有四个参数。当我们只传入三个参数时,系统会将 re.I 视为第三个参数,所以它没起作用。若要让这里的 re.I 起作用,写成 flags=re.I 就可以了。

五、正则的小实践

1、匹配电话号码

p 是通过 re.compile 函数编译的一个正则表达式对象,该正则表达式为 '\d{3}-\d{6}' ,即匹配三位数字后跟一个连字符再跟六位数字的模式。
使用 p 去查找所有匹配的内容,查找的内容是 '010-628888' ,然后将查找到的结果打印出来。

2、匹配IP

re.search 匹配的内容是一个由四个部分组成的字符串,每个部分都是一个点分隔的十进制数,范围在 0 到 255 之间。具体来说,第一个部分可以是 0 到 255 之间的任意一个数,第二个部分也可以是 0 到 255 之间的任意一个数,第三个部分同样可以是 0 到 255 之间的任意一个数,第四个部分也可以是 0 到 255 之间的任意一个数。例如,192.168.1.1 就符合这个模式。re.search 函数在给定的字符串 "192.168.1.1" 中查找是否存在这样的模式。

你可能想看:
« 上一篇
下一篇 »

相关推荐

python爬虫教程PDF,Python爬虫书PDF

2026年09月02日

30阅读

外国教程python,python编程教学视频

2026年09月02日

25阅读

python简明教程沈洁元,python详细基础教程

2026年09月02日

21阅读

python库包教程,python 包

2026年09月02日

26阅读

python教程大全集,python教程600集

2026年09月02日

26阅读

python入门教程完整版,python零基础入门全套教程视频

2026年09月02日

22阅读