从零开始学习人工智能(Python高级教程)Day6-Python3 正则表达式

一、Python3 正则表达式

正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。

在 Python 中,使用re 模块来处理正则表达式。

re 模块提供了一组函数,允许你在字符串中进行模式匹配、搜索和替换操作。

re 模块使 Python 语言拥有完整的正则表达式功能。

本章节主要介绍 Python 中常用的正则表达式处理函数,如果你对正则表达式不了解,可以查看我们的 正则表达式 - 教程

1.re.match函数

re.match 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match() 就返回 None。

函数语法

复制代码
re.match(pattern, string, flags=0)
复制代码
import re
#re.match()函数用于查找字符串的开头是否匹配正则表达式,如果字符串开头匹配正则表达式,则返回一个Match对象,否则返回None。
print(re.match('www', 'www.runoob.com').span()) # 在起始位置匹配
# 首先尝试在 'www.runoob.com' 的起始位置匹配 'www'。
# 由于匹配成功,re.match() 返回一个 Match 对象。然后,.span() 方法被调用,返回一个元组 (0, 3),
# 表示 'www' 在原字符串中的位置是从索引 0 开始到索引 3 结束(不包括索引 3 的字符)

print(re.match('com', 'www.runoob.com'))        # 不在起始位置匹配,返回None

匹配成功 re.match 方法返回一个匹配的对象,否则返回 None

我们可以使用 group(num) 或 groups() 匹配对象函数来获取匹配表达式

匹配对象方法 描述
group(num=0) 匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。
groups() 返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。
复制代码
line = "Cats are smarter than dogs"
matchObj = re.match(r'(.*) are (.*?) .*', line, re.M | re.I)
# re.match(pattern, string, flags=0): 这是 Python 正则表达式模块 re 中的一个函数,用于在字符串的起始位置匹配正则表达式。
# 如果匹配成功,则返回一个 Match 对象;如果匹配失败,则返回 None。

# pattern: 在这里是一个字符串 r'(.*) are (.*?) .*',它是一个正则表达式模式。
# .* 表示任意匹配除换行符(\n、\r)之外的任何单个或多个字符
# (.*?) 表示"非贪婪"模式,只保存第一个匹配到的子串
# 这里的 r 表示原始字符串,即不处理其中的转义字符,直接将其作为正则表达式的内容来处理。

# string: 这里是 line,即要进行匹配操作的字符串。
# 在这个例子中,line 的值是 "Cats are smarter than dogs"。

# flags: 这里使用了 re.M 和 re.I 两个标志。re.M 表示多行模式,这种模式下,
# ^ 和 $ 表示每一行的开始和结束,而不是整个字符串的开始和结束。
# re.I 表示忽略大小写模式,使匹配过程不区分大小写。
# re.M | re.I 使用了按位或操作符 | 来合并这两个标志,表示在匹配时同时使用多行模式和忽略大小写模式。

#group()方法用于获得匹配的字符串。
#group(1)方法用于获得第一个分组匹配的字符串。
#group(2)方法用于获得第二个分组匹配的字符串。
#groups()方法用于获得所有分组匹配的字符串。
if matchObj:
    print("matchObj.group() : ", matchObj.group())
    print("matchObj.group(1) : ", matchObj.group(1))
    print("matchObj.group(2) : ", matchObj.group(2))
    print("matchObj.groups() : ", matchObj.groups())
else:
    print("No match!!")

2. re.search方法

re.search 扫描整个字符串并返回第一个 成功的匹配,用法与match类似。

函数语法:

复制代码
re.search(pattern, string, flags=0)

函数参数说明:

参数 描述
pattern 匹配的正则表达式
string 要匹配的字符串。
flags 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。参见:正则表达式修饰符 - 可选标志
复制代码
import re

print(re.search('www', 'www.runoob.com').span())  # 在起始位置匹配
#输出:(0, 3)

print(re.search('com', 'www.runoob.com').span())  # 不在起始位置匹配(与match有区别)
#输出:(11, 14)    

匹配成功re.search方法返回一个匹配的对象,否则返回None。

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

匹配对象方法 描述
group(num=0) 匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。
groups() 返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。

3.re.match 与 re.search的区别

re.match 只匹配字符串的开始,如果字符串开始不符合 正则表达式,则匹配失败 ,函数返回 None,而 re.search 匹配整个 字符串,直到 找到一个匹配

4.检索和替换

Python 的re模块提供了re.sub用于替换字符串中的匹配项。

语法:

复制代码
re.sub(pattern, repl, string, count=0, flags=0) 

参数:

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

前三个为必选参数,后两个为可选参数。

复制代码
phone = "2004-959-559 # 这是一个电话号码"

# 删除字符串中的 Python注释
num = re.sub(r'#.*$', "", phone)
# 匹配字符串中的井号(#)字符。
# .* 匹配井号后面的所有字符,直到遇到换行符(非贪婪模式)。
# $ 匹配字符串的结尾。
print("电话号码 : ", num)  # 输出:2004-959-559

# 移除非数组字符
num = re.sub(r'\D', "", phone)
# \D 是一个正则表达式元字符,它匹配任何不是数字的字符。
# D 是 d 的反义词,d 匹配数字(等价于 [0-9]),而 D 匹配非数字(等价于 [^0-9])。
print("电话号码 : ", num)  # 输出:2004959559

4.1 repl 参数是一个函数

复制代码
# repl为替换函数,参数为匹配到的内容,返回值为替换后的内容。
# 将匹配的数字乘以 2
def double(matched):
    value = int(matched.group('value'))
    return str(value * 2)

s = 'A23G4HFD567'

print(re.search(r'(?P<value>\d+)', s).group(1))  # 输出:23
print(re.search(r'(?P<value>\d+)', s).groups())  # 输出:('23',)

for match in re.finditer(r'(?P<value>\d+)', s):
    print(match.group(1))  # 输出:23 4 567


print(re.sub('(?P<value>\d+)', double, s))  # 输出:A46G8HFD1134
# (?P<value>\d+): 这是一个命名捕获组,
# 用于从匹配的子串中提取特定部分。(?P<name>...) 是Python中命名捕获组的语法,
# 其中name是你为该捕获组指定的名称,在这里名称为 value。
# \d+: 这个模式用于匹配一个或多个数字。
# \d 是一个正则表达式元字符,表示匹配任何数字字符(等价于 [0-9]),后面的 + 表示匹配前面的元素一次或多次。

4.2 compile 函数

compile 函数 用于编译正则表达式,生成一个正则表达式( Pattern )对象,供 match() 和 **search()**这两个函数使用。

语法格式为:

复制代码
re.compile(pattern[, flags])

参数:

  • **1.pattern :**一个字符串形式的正则表达式

  • 2.flags 可选,表示匹配模式,比如忽略大小写,多行模式等,具体参数为:

    • re.IGNORECASE 或 re.I - 使匹配对大小写不敏感
    • re.L 表示特殊字符集 \w, \W, \b, \B, \s, \S 依赖于当前环境
    • re.MULTILINE 或 re.M - 多行模式 ,改变 ^ 和 $ 的行为,使它们匹配 字符串的每一行开头结尾
    • re.DOTALL 或 re.S - 使 . 匹配包括换行符在内的任意字符。
    • re.ASCII - 使 \w, \W, \b, \B, \d, \D, \s, \S 仅匹配 ASCII 字符。
    • re.VERBOSE 或 re.X - 忽略空格和注释,可以更清晰地组织复杂的正则表达式。

    这些标志可以单独使用,也可以通过**按位或'|'**组合使用。例如,re.IGNORECASE | re.MULTILINE 表示同时启用忽略大小写和多行模式。

    compile 函数

    pattern = re.compile(r'\d+') # 编译正则表达式: \d+

    r'\d+' 是一个正则表达式模式。

    r 表示原始字符串(raw string),即不处理其中的转义字符

    \d 是正则表达式中的一个元字符,表示匹配任何数字字符(等价于 [0-9])。

    + 是一个量词,表示匹配前面的元素一次或多次。因此,\d+ 用于匹配一个或多个连续的数字。

    使用 compile 函数编译的正则表达式可以重复使用,提高效率。

    print(pattern.match('one123one')) #输出:None
    print(pattern.match('one123four',3,6))
    #输出:<re.Match object; span=(3, 6), match='123'>

在上面,当匹配成功时返回一个 Match 对象,其中:

  • group([group1, ...]) 方法用于获得一个或多个分组匹配的字符串,当要获得整个匹配的子串时,可直接使用 group()group(0)

  • start([group]) 方法用于获取分组匹配的子串整个字符串 中的起始位置(子串第一个字符的索引),参数默认值为 0;

  • end([group]) 方法用于获取分组匹配的子串 在整个字符串中的结束位置 (子串最后一个字符的索引+1),参数默认值为 0;

  • span([group]) 方法返回 (start(group), end(group))

    compile 函数

    pattern = re.compile(r'\d+') # 编译正则表达式: \d+

    r'\d+' 是一个正则表达式模式。

    r 表示原始字符串(raw string),即不处理其中的转义字符

    \d 是正则表达式中的一个元字符,表示匹配任何数字字符(等价于 [0-9])。

    + 是一个量词,表示匹配前面的元素一次或多次。因此,\d+ 用于匹配一个或多个连续的数字。

    使用 compile 函数编译的正则表达式可以重复使用,提高效率。

    print(pattern.match('one123one')) #输出:None
    m=pattern.match('one123four',3,6)
    print(m)
    #输出:<re.Match object; span=(3, 6), match='123'>

    print(m.group()) # 输出:123
    print(m.group(0)) # 输出:123
    print(m.start()) # 输出:3
    print(m.end()) # 输出:6
    print(m.span()) # 输出:(3, 6)

4.3 findall

在字符串中找到正则表达式所匹配的所有子串,并返回一个列表 ,如果有多个匹配模式 ,则返回元组列表,如果没有找到匹配的,则返回空列表。

注意: matchsearch匹配一次 findall 匹配所有

语法格式为:

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

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

参数:

  • pattern 匹配模式。

  • string 待匹配的字符串。

  • pos 可选参数,指定字符串的起始位置,默认为 0。

  • endpos 可选参数,指定字符串的结束位置,默认为字符串的长度。

    #findall
    s = 'hello 123 world, hello 456 python'
    pattern = re.compile(r'\d+')
    print(pattern.findall(s)) # 输出:['123', '456']
    print(pattern.findall(s,10,25)) # 输出:['4']

    多个匹配模式,返回元组列表:

    result = re.findall(r'(\w+)=(\d+)', 'set width=20 and height=10')

    模式 (\w+)=(\d+) 会匹配所有的单词字符后跟一个等号,然后是数字字符。

    print(result) # 输出:[('width', '20'), ('height', '10')]

5.re.finditer

和 findall 类似,在字符串中找到正则表达式所匹配的所有子串 ,并把它们作为一个迭代器返回。

复制代码
re.finditer(pattern, string, flags=0)

参数:

参数 描述
pattern 匹配的正则表达式
string 要匹配的字符串。
flags 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。参见:正则表达式修饰符 - 可选标志
复制代码
#finditer
it = re.finditer(r"\d+", "12a32bc43jf3")
for match in it:
    print(match.group())
    # 输出:12 32 43 3

6.re.split

plit 方法按照能够匹配的子串将字符串分割后返回列表,它的使用形式如下:

复制代码
re.split(pattern, string[, maxsplit=0, flags=0])

参数:

参数 描述
pattern 匹配的正则表达式
string 要匹配的字符串。
maxsplit 分割次数,maxsplit=1 分割一次,默认为 0,不限制次数。
flags 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。参见:正则表达式修饰符 - 可选标志
复制代码
print(re.split(r'\W+', 'runoob,runoob,runoob.') )
#输出:['runoob', 'runoob', 'runoob', '']
# \W 是一个正则表达式元字符,表示匹配任何非单词字符(等价于 [^a-zA-Z0-9_])
# re.split() 会查找字符串中所有符合 \W+ 模式的子串,并以这些子串为分隔符将原字符串分割成多个部分。
# 在字符串 'runoob, runoob, runoob.' 中,\W+ 匹配到的是逗号 ,和句号 .。
# 因此,该字符串会被分割成 ['runoob', 'runoob', 'runoob', ''] 这四个部分。
# 注意最后一个空字符串 '' 的存在,这是因为字符串末尾有一个句号 .,它被当作分隔符,导致在它之后还产生了一个空字符串。



print( re.split('\W+', ' runoob, runoob, runoob.', 1) ) #限制分割次数为1
# 输出:['', 'runoob, runoob, runoob.']

print(re.split(r'(\W+)', 'runoob, runoob, runoob.'))
# 输出:['runoob', ', ', 'runoob', ', ', 'runoob', '.', '']
# r'(\W+)' 是一个正则表达式模式。
# r 表示原始字符串,这样在字符串中使用转义字符时,避免 Python 字符串的转义处理。
# 在这个模式中,\W 是一个正则表达式元字符,它匹配任何非单词字符(等价于 [^a-zA-Z0-9_])。
# + 是一个量词,表示匹配前面的元素一次或多次。因此,\W+ 用于匹配一个或多个连续的非单词字符。
# 括号 () 用于捕获匹配的子串,并将其包含在分割结果中。

7.正则表达式对象

re.RegexObject

**re.compile()**返回 RegexObject 对象。

re.MatchObject

group() 返回被 RE 匹配的字符串。

  • start() 返回匹配开始的位置
  • end() 返回匹配结束的位置
  • span() 返回一个元组包含匹配 (开始,结束) 的位置

8.正则表达式修饰符 - 可选标志

正则表达式可以包含一些可选标志修饰符来控制匹配的模式。

以下标志可以单独使用,也可以通过按位或(|)组合使用。例如,re.IGNORECASE | re.MULTILINE 表示同时启用忽略大小写和多行模式。

修饰符 描述 实例
re.IGNORECASE 或 re.I 使匹配对大小写不敏感 import re pattern = re.compile(r'apple', flags=re.IGNORECASE) result = pattern.match('Apple') print(result.group()) # 输出: 'Apple'
re.MULTILINE 或 re.M 多行匹配,影响 ^ 和 $,使它们匹配字符串的每一行的开头和结尾。 import re pattern = re.compile(r'^\d+', flags=re.MULTILINE) text = '123\n456\n789' result = pattern.findall(text) print(result) # 输出: ['123', '456', '789']
re.DOTALL 或 re.S: 使 . 匹配 包括换行符在内的任意字符。 import re pattern = re.compile(r'a.b', flags=re.DOTALL) result = pattern.match('a\nb') print(result.group()) # 输出: 'a\nb'
re.ASCII 使 \w, \W, \b, \B, \d, \D, \s, \S 仅匹配 ASCII 字符。 import re pattern = re.compile(r'\w+', flags=re.ASCII) result = pattern.match('Hello123') print(result.group()) # 输出: 'Hello123'
re.VERBOSE 或 re.X 忽略空格和注释,可以更清晰地组织复杂的正则表达式。 import re pattern = re.compile(r''' \d+ # 匹配数字 [a-z]+ # 匹配小写字母 ''', flags=re.VERBOSE) result = pattern.match('123abc') print(result.group()) # 输出: '123abc'

9.正则表达式模式

模式字符串使用特殊的语法来表示一个正则表达式。

字母和数字表示他们自身。一个正则表达式模式中的字母和数字匹配同样的字符串。

多数字母和数字前加一个反斜杠时会拥有不同的含义。

标点符号只有被转义时才匹配自身,否则它们表示特殊的含义。

反斜杠本身需要使用反斜杠转义。

由于正则表达式通常都包含反斜杠,所以你最好使用原始字符串来表示它们。模式元素(如 r'\t',等价于 \\t )匹配相应的特殊字符。

下表列出了正则表达式模式语法中的特殊元素。如果你使用模式的同时提供了可选的标志参数,某些模式元素的含义会改变。

模式 描述
^ 匹配字符串的开头
$ 匹配字符串的末尾
. 匹配任意字符换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。
[...] 用来匹配所包含的任意一个字符,例如 [amk] 匹配 'a','m'或'k'
[^...] 不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符。
re* 匹配0个或多个的表达式。
re+ 匹配1个或多个的表达式。
re? 匹配0个或1个由前面的正则表达式 定义的片段,非贪婪方式
re{ n} 匹配n个前面表达式。例如,"o{2}"不能匹配"Bob"中的"o",但是能匹配"food"中的两个o。
re{ n,} 精确匹配n个 前面表达式。例如,"o{2,} "不能匹配"Bob"中的"o",但能匹配 "foooood"中的所有o。"o{1,} "等价于"o+ "。"o{0,} "则等价于"o*"。
re{ n, m} 匹配 n 到 m 次由前面的正则表达式定义的片段,贪婪方式
a| b 匹配ab
(re) 匹配 括号内的表达式,也表示一个组
(?imx) 正则表达式包含 三种可选标志:i(大小写), m(多行), 或 x(忽略空格和注释) 。只影响括号中的区域。
(?-imx) 正则表达式关闭 i, m, 或 x 可选标志。只影响括号中的区域。
(?: re) 类似 (...), 但是不表示一个组
(?imx: re) 在括号中使用i, m, 或 x 可选标志
(?-imx: re) 在括号中不使用i, m, 或 x 可选标志
(?#...) 注释.
(?= re) 前向肯定界定符。如果所含正则表达式,以 ... 表示,在当前位置成功匹配时成功,否则失败。但一旦所含表达式已经尝试,匹配引擎根本没有提高;模式的剩余部分还要尝试界定符的右边。
(?! re) 前向否定界定符 。与肯定界定符相反;当所含表达式不能在字符串当前位置匹配时成功。
(?> re) 匹配的独立模式,省去回溯。
\w 匹配数字字母下划线
\W 匹配数字字母下划线
\s 匹配任意空白字符,等价于 [\t\n\r\f]。
\S 匹配任意空字符
\d 匹配任意数字,等价于 [0-9]。
\D 匹配任意非数字
\A 匹配字符串开始
\Z 匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。
\z 匹配字符串结束
\G 匹配最后匹配完成位置
\b 匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。
\B 匹配单词边界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。
\n, \t, 等。 匹配一个换行符。匹配一个制表符, 等
\1...\9 匹配第n个分组的内容。
\10 匹配第n个分组的内容,如果它经匹配。否则指的是八进制字符码的表达式。

10.正则表达式实例

字符匹配
实例 描述
python 匹配 "python".
字符类
实例 描述
[Pp]ython 匹配 "Python" 或 "python"
rub[ye] 匹配 "ruby" 或 "rube"
[aeiou] 匹配中括号内的任意一个字母
[0-9] 匹配任何数字。类似于 [0123456789]
[a-z] 匹配任何小写字母
[A-Z] 匹配任何大写字母
[a-zA-Z0-9] 匹配任何字母及数字
[^aeiou] 除了aeiou字母以外的所有字符
[^0-9] 匹配除了数字外的字符
特殊字符类
实例 描述
. 匹配除 "\n" 之外 的任何单个字符。要匹配 包括 '\n' 在内的任何字符 ,请使用象 '[.\n]' 的模式。
\d 匹配一个数字字符。等价于 [0-9]。
\D 匹配一个数字字符。等价于 [^0-9]。
\s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。
\S 匹配任何空白字符。等价于 [^ \f\n\r\t\v]。
\w 匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]'。
\W 匹配任何单词字符。等价于 '[^A-Za-z0-9_]'。

参考:Python3 正则表达式 | 菜鸟教程https://www.runoob.com/python3/python3-reg-expressions.html

相关推荐
田辛 | 田豆芽4 分钟前
【Python】通过`Editable Install`模式详解,解决Python开发总是import出错的问题
开发语言·python·包管理
LVerrrr1 小时前
Missashe考研日记-day34
学习·考研
编程自留地1 小时前
第11次:用户注册(简要版)
python·django
Leo.yuan1 小时前
直播数据大屏是什么?企业应如何构建直播数据大屏?
大数据·数据库·python·信息可视化·数据分析
缘友一世2 小时前
深度学习系统学习系列【3】之血液检测项目
人工智能·深度学习·学习
API小爬虫2 小时前
如何用爬虫获得按关键字搜索淘宝商品
java·爬虫·python
一个天蝎座 白勺 程序猿2 小时前
Python爬虫(14)Python爬虫数据存储新范式:云原生NoSQL服务实战与运维成本革命
爬虫·python·云原生
xiufeia3 小时前
记录学习的第三十五天
学习
夏季疯3 小时前
学习笔记:黑马程序员JavaWeb开发教程(2025.3.29)
java·笔记·学习
xixixiLucky4 小时前
Selenium Web自动化测试学习笔记(一)
笔记·学习·selenium