文章目录
re模块主要定义了 9个常量、12个函数、1个异常
。
1. 正则表达式的模式——pattern
模式字符串使用特殊的语法来表示一个正则表达式:
- 字母和数字表示他们自身。一个正则表达式模式中的
字母和数字匹配同样的字符串
。- 多数字母和数字
前加一个反斜杠时会拥有不同的含义
。标点符号只有被转义时才匹配自身
,否则它们表示特殊的含义。- 反斜杠本身需要使用反斜杠转义。
- 由于正则表达式通常都包含反斜杠,所以你最好使用原始字符串来表示它们。
模式元素(如 r'\t',等价于 '\\t')匹配相应的特殊字符
。
下表列出了正则表达式模式语法中的特殊元素。如果你使用模式的同时提供了可选的标志参数,某些模式元素的含义会改变。
模式 | 描述 |
---|---|
^ | 匹配字符串的开头 |
$ | 匹配字符串的末尾。 |
. | 匹配任意字符 ,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。 |
[…] | 用来表示一组字符,单独列出 :[abc] 匹配’a’,‘b’或’c’ |
[^…] | 不在[]中的字符 :[^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 次由前面的正则表达式定义的片段,贪婪方式 |
(re) | 对正则表达式分组并记住匹配的文本 |
(?imx) | 正则表达式包含三种可选标志:i, m, 或 x 。只影响括号中的区域。 |
(?-imx) | 正则表达式关闭 i, m, 或 x 可选标志。只影响括号中的区域。 |
(?: re) | 类似 (…), 但是不表示一个组 |
(?imx: re) | 在括号中使用i, m, 或 x 可选标志 |
(?-imx: re) | 在括号中不使用i, m, 或 x 可选标志 |
(?#…) | 注释. |
(?= re) | 前向肯定界定符。如果所含正则表达式,以 … 表示,在当前位置成功匹配时成功,否则失败。但一旦所含表达式已经尝试,匹配引擎根本没有提高;模式的剩余部分还要尝试界定符的右边。 |
(?! re) | 前向否定界定符。与肯定界定符相反;当所含表达式不能在字符串当前位置匹配时成功 |
(?> re) | 匹配的独立模式,省去回溯。 |
\w | 匹配包括下划线的任何单词字符 。等价于’[A-Za-z0-9_]'。 |
\W | 匹配任何非单词字符 。等价于 ‘[^A-Za-z0-9_]’。 |
\s | 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。。 |
\S | 匹配任何非空白字符 。等价于 [^ \f\n\r\t\v]。 |
\d | 匹配任意数字 ,等价于 [0-9]. |
\D | 匹配一个非数字字符。等价于 [^0-9]。 |
\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个分组的内容,如果它经匹配。否则指的是八进制字符码的表达式。 |
2. 正则表达式常量——修饰符
(1)常量理解
常量即表示不可更改的变量,一般用于做标记。re模块中有9个常量,常量的值都是int类型,并且所有的常量都是在RegexFlag枚举类来实现
需要说明的是,这9个常量值是可以叠加使用的,叠加时请使用 |
符号。
修饰符 | 简写 | 描述 |
---|---|---|
re.IGNORECASE | re.I | 进行忽略大小写匹配 。 |
re.ASCII | re.A | ASCII表示ASCII码的意思,让 \w, \W, \b, \B, \d, \D, \s 和 \S 只匹配ASCII,而不是Unicode。 |
re.DOTALL | re.S | DOT表示.,ALL表示所有,连起来就是.匹配所有,包括换行符\n。默认模式下.是不能匹配行符\n的。 |
re.MULTILINE | re.M | 多行模式,当某字符串中有换行符\n,默认模式下是不支持换行符特性的,比如:行开头 和 行结尾,而多行模式下是支持匹配行开头的。 |
re.VERBOSE | re.X | 详细模式,可以在正则表达式中加注解。 |
re.LOCALE | re.L | 由当前语言区域决定 \w, \W, \b, \B 和大小写敏感匹配,这个标记只能对byte样式有效。这个标记官方已经不推荐使用 ,因为语言区域机制很不可靠,它一次只能处理一个 "习惯”,而且只对8位字节有效。 |
re.UNICODE | re.U | 与 ASCII 模式类似,匹配unicode编码支持的字符,但是 Python3 默认字符串已经是Unicode ,所以有点冗余。 |
re.DEBUG | 显示编译时的debug信息。 | |
re.TEMPLATE | re.T |
9个常量在re常用函数中都可以使用。前5个(IGNORECASE、ASCII、DOTALL、MULTILINE、VERBOSE)较为实用,两个(LOCALE、UNICODE)官方不建议使用、两个(TEMPLATE、DEBUG)试验性功能,不能依赖。
下面使用代码来更直观地查看常用正则表达式常量的使用。
(2)re.IGNORECASE
import re
text = 'QLEE'
pattern = 'qlee'
print('默认模式:', re.findall(pattern, text))
print('忽略大小写模式:', re.findall(pattern, text, re.IGNORECASE))
输出:
默认模式: []
忽略大小写模式: ['QLEE']
(3)re.ASCII
import re
text = '我是QLEE大家hao'
pattern = r'\w+'
print('unicode:', re.findall(pattern, text))
print('ASCII:', re.findall(pattern, text, re.ASCII))) #只匹配ASCII编码支持的字符
输出:
unicode: ['我是QLEE大家hao']
ASCII: ['QLEE', 'hao']
(4)re.DOTALL
import re
text = '我是QLEE\n大家hao'
pattern = r'.*'
print('默认模式:', re.findall(pattern, text)) #默认模式可以去掉换行符
print('匹配所有模式:', re.findall(pattern, text, re.DOTALL)) #换行符也匹配
输出:
默认模式: ['我是QLEE', '', '大家hao', '']
匹配所有模式: ['我是QLEE\n大家hao', '']
3. 正则表达式函数
需要说明的是:查找一个匹配项(search、match、fullmatch)的函数返回值都是一个 匹配对象Match ,需要通过match.group() 获取匹配值
。
group() 返回被 RE 匹配的字符串。
类型 | 说明 |
---|---|
group(num=0) | 匹配的整个表达式的字符串,当要获得整个匹配的子串时,可直接使用 group() 或 group(0),第一个为group(1),其他依次类推 |
groups() | 返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。 |
start():
返回匹配开始的位置end():
返回匹配结束的位置span():
返回一个元组包含匹配 (开始,结束) 的位置
- 举例说明
import re
pattern = r'([a-z]+) ([a-z]+)'
text = 'Hello World Wide Web' # 查待匹配的字符串
tmp = re.match(pattern, text, re.I)
print('match : ', tmp)
print('group : ', tmp.group()) #所有匹配的字符串
print('group(1) : ', tmp.group(1)) #第一个匹配的字符串
print('start : ', tmp.start()) #所有的开始
print('end : ', tmp.end())# 所有的结束
print('span : ', tmp.span(2)) #第2个的开始与结束
输出:
match : <_sre.SRE_Match object; span=(0, 11), match='Hello World'>
group : Hello World
group(1) : Hello
start : 0
end : 11
span : (6, 11)
(1)查找一个匹配项——match、search和fullmatch
re.match
: 必须从字符串开头
匹配re.search
: 查找任意位置
的匹配项re.fullmatch
: 整个字符串与正则完全匹配
import re
text = 'aqleebqlee,cqlee'
pattern = 'qlee'
# match,只匹配开头
print('match:', re.match(pattern, text))
# search,匹配任意位置
print('search:', re.search(pattern, text))
# fullmatch,全部匹配
print('fullmatch', re.fullmatch(pattern, text))
print('group获取匹配的值:', re.search(pattern, text).group())
输出:
match: None
search: <_sre.SRE_Match object; span=(1, 5), match='qlee'>
fullmatch None
group获取匹配的值: qlee
search函数是在字符串中任意位置匹配,只要有符合正则表达式的字符串就匹配成功,其实有两个匹配项,但search函数值返回一个。
而match函数是要从头开始匹配,而字符串开头多了个字母a,所以无法匹配,fullmatch函数需要完全相同,故也不匹配!
(2)查找多个匹配项——findall、finditer
re.findall
: 从字符串任意位置查找,返回一个列表
re.finditer
:从字符串任意位置查找,返回一个迭代器
两个方法基本类似,只不过一个是返回列表,一个是返回迭代器。我们知道列表是一次性生成在内存中,而迭代器是需要使用时一点一点生成出来的,内存使用更优。
import re
text = 'aqleebqlee,cqlee'
pattern = 'qlee'
# findall,返回所有匹配值,组成列表形式
print('findall: ', re.findall(pattern, text))
# finditer,返回匹配的迭代器,需要转化为list
print('finditer: ', list(re.finditer(pattern, text)))
输出:
findall: ['qlee', 'qlee', 'qlee']
finditer: [<_sre.SRE_Match object; span=(1, 5), match='qlee'>, <_sre.SRE_Match object; span=(6, 10), match='qlee'>, <_sre.SRE_Match object; span=(12, 16), match='qlee'>]
(3)分割——split
- 函数形式
re.split(pattern, string, maxsplit=0, flags=0)
- pattern:分开 string
- maxsplit: 表示最多进行分割次数
- flags:表示模式
import re
text = 'aqleebqlee,cqlee'
pattern = 'qlee'
print('split: ', re.split(pattern, text, maxsplit=1, flags=re.IGNORECASE))
输出:
split: ['a', 'bqlee,cqlee']
(4)替换——sub、subn
re.subn与sub函数功能一致,只不过subn返回一个元组(字符串, 替换次数)
。
re.sub(pattern, repl, string, count=0, flags=0)
- repl替换掉string中被pattern匹配的字符
- count表示最大替换次数
- flags表示正则表达式的常量
import re
text = 'aqleebqlee,cqlee'
pattern = ','
repl = '/'
# 将','换成'/'
print('sub: ', re.sub(pattern, repl, text, count=2, flags=re.IGNORECASE))
输出:
sub: aqleebqlee/cqlee
(5)编译正则项——template、compile
compile
函数 与 template
函数功能为将正则表达式的样式编译为一个正则表达式对象
(正则对象Pattern),这个对象与re模块有同样的正则函数。
这一块暂时用得较少,暂时不做讲解。
(6)其他——escape、purge
- escape
re.escape(pattern) 可以转义正则表达式中具有特殊含义的字符。
pattern = r'qlee\.qlee\*'
等价于:
pattern = re.escape(qlee.qlee*)
re.escape(pattern) 看似非常好用省去了我们自己加转义,但是使用它很容易出现转义错误的问题,所以并不建议使用它转义,而建议大家自己手动转义
!
- purge
re.purge() 函数作用就是清除正则表达式缓存
4. 一些简短示例
(1)常用匹配模式
例子 | 描述 |
---|---|
[Pp]ython | 匹配 “Python” 或 “python” |
[aeiou] | 匹配中括号内的任意一个字母 |
[^aeiou] | 除了aeiou字母以外的所有字符 |
[0-9] | 匹配任何数字。类似于 [0123456789] |
[a-z] | 匹配任何小写字母 |
[A-Z] | 匹配任何大写字母 |
[a-zA-Z0-9] | 匹配任何字母及数字 |
[^0-9] | 匹配除了数字外的字符 |
(2)多个匹配模式——提取字符串和字符
import re
# 提取字符和数字
'''
\w: 匹配包括下划线的任何单词字符
\d: 匹配数字
+: 匹配一个或多个,要不然只会匹配一个字符和一个数字
'''
result = re.findall(r'(\w+)=(\d+)', 'set width=20 and height=10')
print(result)
输出:
[('width', '20'), ('height', '10')]