Python 正则表达式
李俊才的个人博客
已入驻阿里云
邮箱 :291148484@163.com
本文地址:
- https://developer.aliyun.com/article/
- https://blog.csdn.net/qq_28550263/article/details/123482797
相关文章推荐:
目 录
- 2.1 定位符:描述字符的边界
- 2.2 限定符:描述重复匹配的次数
- 2.3 字符描述
- 2.4 管道符:使用“或”匹配逻辑
- 2.5 转移符:将特殊符号标识为普通字符
- 2.6 分组
- 2.7 flags修饰符
- 3.1.1 re.ASCII:让 \w, \W, \b, \B, \d, \D, \s 和 \S 只匹配ASCII
- 3.1.2 re.DEBUG:显示编译时的debug信息
- 3.1.3 re.IGNORECASE:忽略大小写匹配
- 3.1.4 re.LOCALE:不推荐使用!
- 3.1.5 re.MULTILINE设置
^
和$
用于包括整个字符串的开始和结尾的每一行 - 3.1.6 re.DOTALL:让 ‘.’ 特殊字符匹配任何字符
- 3.1.7 re.VERBOSE:编写更具可读性更友好的正则表达式
- 3.2.1 re.compile 方法:___编译为正则表达式对象
- 3.2.2 re.search 方法: ___搜索第一个匹配位置
- 3.2.3 re.match 方法: ___从字符串开始处及逆行匹配
- 3.2.4 re.fullmatch 方法:_对整个字符串进行匹配
- 3.2.5 re.split 方法: _____根据正则表达式分割字符串
- 3.2.6 re.findall 方法:____搜索所有满足正则表达式的字符
- 3.2.7 re.finditer 方法:____找到所匹配的所有子串
- 3.2.8 re.sub 方法:_______返回通过使用 repl 替换在 string 最左边非重叠出现的 pattern 而获得的字符串
- 3.2.9 re.subn 方法:______字符串替换
- 3.2.10 re.escape 方法:___转义 pattern 中的特殊字符
- 3.2.11 re.purge 方法:____用于清除正则表达式的缓存
1. 概述
正则表达式用于描述各种复杂的字符串关系,使用正则表达式能够更加灵活便捷地处理字符串。
2. 字符串规则描述符
2.1 定位符:描述字符的边界
符号 | 描述 | 说明 |
^ | 匹配一个字符串的起始字符 | - |
$ | 匹配一个字符串的结尾字符 | - |
\b | 匹配一个单词的边界 | - |
\B | 匹配非 单词边界 |
相当于\b 匹配的反集 |
2.2 限定符:描述重复匹配的次数
符号 | 描述 | 说明 |
? | 匹配该限定符前的字符0 或1 次 |
如 colou?r 可以匹配colour 和color |
+ | 匹配该限定符前的字符1 或多 次 |
如 hel+o 可以匹配helo 、hello 、helllo 、… |
* | 匹配该限定符前的字符0 或多 次 |
如 hel*o 可以匹配heo 、helo 、hello 、helllo 、… |
{n} | 匹配该限定符前的字符n 次 |
如 hel{2}o 只可以匹配hello |
{n,} | 匹配该限定符前的字符最少n次 |
如 hel{2,}o 可以匹配hello 、helllo 、… |
{n,m} | 匹配该限定符前的字符最少n次 ,最多m次 |
如 hel{2,3}o 只可以匹配hello 和 helllo |
【例】写出从字符串string
的任意一行中匹配颜色名
和颜色值
的正则表达式:
# 待提取的字符串string='''$navajowhite: #FFDEAD !default;$moccasin: #FFE4B5 !default;$bisque: #FFE4C4 !default;$mistyrose: #FFE4E1 !default;$blanchedalmond: #FFEBCD !default;$lavenderblush: #FFF0F5 !default;'''
目标 | 表达式 | 说明 |
提取颜色名 | r'\w{1,15} |
考虑到上面颜色名单词最长没有超过15个字符串,最短肯定得有字符,所以写了{1,15} ,但也可以是其它的合理值即可。 |
提取颜色值 | r'#.{6}', |
颜色值由# 符号开头,一共由六位十六进制数字,十六进制数字为是个阿拉伯数字字符加A、B、C、D、E、F五个英文字符构成。 |
2.3 字符描述
符号 | 描述 | 说明 |
\d | 匹配任意数字 | |
\s | 匹配任意空白符 | |
\w | 匹配任意字母、数字、下划线、汉字等 | |
\D | 匹配任意非 数字 |
|
\S | 匹配任意非 空白符 |
|
\W | 匹配除了 字母、数字、下划线、汉字以外的字符 |
|
. | 匹配除了换行符 以外的任意字符 |
形式 | 描述 | 说明 |
[A-Z] | 区间匹配,匹配字母表该区间所有大写字母 | 如[C-F] 匹配字符C、D、E、F |
[a-z] | 区间匹配,匹配字母表该区间所有小写字母 | 如[c-f] 匹配字符c、d、e、f |
[0-9] | 区间匹配,匹配该区间内的所有数字 | 如[3-6] 匹配字符3、4、5、6 |
[ABCD] | 列表匹配,匹配[] 中列出的所有字母 |
如这里列出的A、B、C、D都会被匹配 |
[^ABCD] | 列表排除,匹配除了[] 中列出的字符外的所有字符 |
如这里列出的A、B、C、D都会被排除而匹配其它字符 |
例如,匹配IPV4地址:
import re url = 'https://127.0.0.1:8888/notebooks/Untitled.ipynb' res = re.compile(r'[1-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[1-9]{1,3}').findall(url)[0]
2.4 管道符:使用“或”匹配逻辑
管道符就是一根竖线:|
,再正则表达式中标识”或“。由于匹配方向时从左向右进行的,假如有两个正则表达式A
和B
,那么使用 A|B
匹配字符串时,只要前一个样式完全匹配成功,那么后一个就不再匹配。
2.5 转义字符:将特殊符号标识为普通字符
在正则表达式中用于标识特殊含义的符号如.
用于标识一个任意的非换行符字符,^
标识起始字符,等等。但是我们希望匹配到这些字符本身也是经常遇到的情况,如IPV4地址使用.
作为分割符。因此我们如果需要完整提取IPV4地址就需要表示.
本身。由于直接使用点已经有了其它的含义,因此我们使用一个\
号进行转义,即使用\.
来表示点(.
)。其它在正则中有特殊含义的符号也可以使用类似的方式。
2.6 分组
与数学计算中采用小括号()
进行算式分组一样,正则模板也能够分组表达,目的是将某一部分正则模板作为一个整体表达,例如模板:
importres='4aderf weew16a dawedb_ewwecs aswed 6aew'res_1=re.compile(r'(we|ew){1}').findall(s) res_2=re.compile(r'(we|ew){2}').findall(s) print(res_1,res_2)
Out[]:
[‘we’, ‘ew’, ‘we’, ‘ew’, ‘we’, ‘we’, ‘ew’] [‘ew’, ‘we’]
这里将(we|ew)
作为一个组,{n}
对改组指定重复匹配的次数。
2.7 flags修饰符
在Python的re
模块中很多方法都可以指定一个flags
参数作为标志位,通过指定这个参数值能够实现一些特殊的功能,详见 3.1 常量 小节。
3. Python 的re
模块 API
3.1 常量
常量 | 简写/相同功能 | 描述 |
re.ASCII | re.A | 用作标志位的 flag ,让 \w, \W, \b, \B, \d, \D, \s 和 \S 只匹配ASCII,而不是Unicode。 |
re.DEBUG | - | 显示编译时的debug信息,没有内联标记。 |
re.IGNORECASE | re.I | 用作标志位的 flag ,进行忽略大小写匹配;表达式如 [A-Z] 也会匹配小写字符。 |
re.LOCALE | re.L | 用作标志位的 flag ,由当前语言区域决定 \w, \W, \b, \B 和大小写敏感匹配。这个标记只能对byte样式有效。 |
re.MULTILINE | re.M | 用作标志位的 flag ,设置^ 和$ 用于包括整个字符串的开始和结尾的每一行。 |
re.DOTALL | re.S | 用作标志位的 flag ,让 ‘.’ 特殊字符匹配任何字符,包括换行符。 |
re.VERBOSE | re.X | 用作标志位的 flag ,这个标记允许你编写更具可读性更友好的正则表达式。通过分段和添加注释。 |
3.1.1 re.ASCII
让 \w
, \W
, \b
, \B
, \d
, \D
, \s
和 \S
只匹配ASCII,而不是Unicode。这只对Unicode样式有效,会被byte样式忽略。相当于前面语法中的内联标志 (?a) 。
3.1.2 re.DEBUG
显示编译时的debug信息,没有内联标记。
3.1.3 re.IGNORECASE
进行忽略大小写匹配;表达式如 [A-Z] 也会匹配小写字符。Unicode匹配(比如 Ü 匹配 ü)同样有用,除非设置了 re.ASCII
标记来禁用非ASCII匹配。当前语言区域不会改变这个标记,除非设置了 re.LOCALE
标记。这个相当于内联标记 (?i)
。
3.1.4 re.LOCALE
由当前语言区域决定 \w
, \W
, \b
, \B
和大小写敏感匹配。这个标记只能对byte样式有效。这个标记不推荐使用,因为语言区域机制很不可靠,它一次只能处理一个 "习惯”,而且只对8位字节有效。Unicode匹配在Python 3 里默认启用,并可以处理不同语言。 这个对应内联标记 (?L)
。
3.1.5 re.MULTILINE
设置^
和$
用于包括整个字符串的开始和结尾的每一行。默认情况下,’^’
匹配字符串头,'$'
匹配字符串尾。对应内联标记 (?m)
。
3.1.6 re.DOTALL
让 '.'
特殊字符匹配任何字符,包括换行符;如果没有这个标记,'.'
就匹配 除了 换行符的其他任意字符。对应内联标记 (?s)
。
3.1.7 re.VERBOSE
这个标记允许你编写更具可读性更友好的正则表达式。通过分段和添加注释。空白符号会被忽略,除非在一个字符集合当中或者由反斜杠转义,或者在 *?
, (?:
或者(?P<…>
分组之内。当一个行内有 #
不在字符集和转义序列,那么它之后的所有字符都是注释。
3.2 正则方法
方法 | 描述 |
re.compile(pattern , flags =0) |
将正则表达式的样式编译为一个 正则表达式对象 (正则对象) |
re.search(pattern , string , flags =0) |
扫描整个 字符串 找到匹配样式的第一个位置,并返回一个相应的 匹配对象 |
re.match(pattern , string , flags =0) |
如果 string 开始的0或者多个字符匹配到了正则表达式样式,就返回一个相应的 匹配对象 。 如果没有匹配,就返回 None |
re.fullmatch(pattern , string , flags =0) |
如果整个 string 匹配到正则表达式样式,就返回一个相应的 匹配对象 |
re.split(pattern , string , maxsplit =0, flags =0) |
用 pattern 分开 string |
re.findall(pattern , string , flags =0) |
以字符串或元组的形式返回字符串中模式的所有非重叠匹配 |
re.finditer(pattern , string , flags =0) |
pattern 在 string 里所有的非重复匹配,返回为一个迭代器 iterator 保存了 匹配对象 |
re.sub(pattern , repl , string , count=0 , flags =0) |
返回通过使用 repl 替换在 string 最左边非重叠出现的 pattern 而获得的字符串 |
re.subn(pattern , repl , string , count =0, flags =0) |
作用与 sub () 相同,但是返回一个元组 (字符串, 替换次数) |
re.escape(pattern ) |
转义 pattern 中的特殊字符 |
re.purge() | 用于清除正则表达式的缓存 |
3.2.1 re.compile 方法
扫描整个 字符串 找到匹配样式的第一个位置,并返回一个相应的 匹配对象。如果没有匹配,就返回一个 None ; 注意这和找到一个零长度匹配是不同的。
1. 调用格式
格式 | 参数 | |
|
pattern:编译时使用的表达式字符串 flags:编译标志为。用于修改正则表达式的匹配方式,详见 2.7节 flags修饰符 |
2. 小例子
importre
3.2.2 re.search 方法
如果 string 开始的0或者多个字符匹配到了正则表达式样式,就返回一个相应的 匹配对象 。 如果没有匹配,就返回 None ;注意它跟零长度匹配是不同的。
注意即便是 MULTILINE 多行模式, re.match() 也只匹配字符串的开始位置,而不匹配每行开始。
1. 调用格式
格式 | 参数 | |
|
pattern:编译时使用的表达式字符串 flags:编译标志为。用于修改正则表达式的匹配方式,详见 2.7节 flags修饰符 |
2. 小例子
import re
3.2.3 re.match 方法
如果 string 开始的0或者多个字符匹配到了正则表达式样式,就返回一个相应的 匹配对象 。 如果没有匹配,就返回 None ;注意它跟零长度匹配是不同的。
注意即便是 MULTILINE 多行模式, re.match() 也只匹配字符串的开始位置,而不匹配每行开始。
1. 调用格式
格式 | 参数 | |
|
pattern:编译时使用的表达式字符串 flags:编译标志为。用于修改正则表达式的匹配方式,详见 2.7节 flags修饰符 |
2. 小例子
importrere.match( r'mr_\w+', # pattern'HELLO_EORLD hello_world', # stringre.I# flag)
Out[]:
<re.Match object; span=(0, 11), match=‘HELLO_EORLD’>
3.2.4 re.fullmatch 方法
如果整个 string 匹配到正则表达式样式,就返回一个相应的 匹配对象 。 否则就返回一个 None ;注意这跟零长度匹配是不同的。
1. 调用格式
格式 | 参数 | |
|
pattern:编译时使用的表达式字符串 flags:编译标志为。用于修改正则表达式的匹配方式,详见 2.7节 flags修饰符 |
2. 小例子
importre
3.2.5 re.split 方法
用 pattern 分开 string 。 如果在 pattern 中捕获到括号,那么所有的组里的文字也会包含在列表里。如果 maxsplit 非零, 最多进行 maxsplit 次分隔, 剩下的字符全部返回到列表的最后一个元素。
1. 调用格式
格式 | 参数 | |
|
pattern:编译时使用的表达式字符串 flags:编译标志为。用于修改正则表达式的匹配方式,详见 2.7节 flags修饰符 |
2. 小例子
importrere.split(r'\W+', 'Words, words, words.') # ['Words', 'words', 'words', '']re.split(r'(\W+)', 'Words, words, words.') # ['Words', ', ', 'words', ', ', 'words', '.', '']re.split(r'\W+', 'Words, words, words.', 1) # ['Words', 'words, words.']re.split('[a-f]+', '0a3B9', flags=re.IGNORECASE) # ['0', '3', '9']
如果分隔符里有捕获组合,并且匹配到字符串的开始,那么结果将会以一个空字符串开始。对于结尾也是一样:
re.split(r'(\W+)', '...words, words...') # ['', '...', 'words', ', ', 'words', '...', '']
这样的话,分隔组将会出现在结果列表中同样的位置。样式的空匹配仅在与前一个空匹配不相邻时才会拆分字符串。
re.split(r'\b', 'Words, words, words.') # ['', 'Words', ', ', 'words', ', ', 'words', '.']re.split(r'\W*', '...words...') # ['', '', 'w', 'o', 'r', 'd', 's', '', '']re.split(r'(\W*)', '...words...') # ['', '...', '', '', 'w', '', 'o', '', 'r', '', 'd', '', 's', '...', '', '', '']
3.2.6 re.findall 方法
以字符串或元组的形式返回字符串中模式的所有非重叠匹配。从左到右扫描字符串,匹配项按找到的顺序返回。结果中包含空匹配。
结果取决于模式中捕获组的数量。如果没有组,则返回匹配整个模式的字符串列表。如果只有一个组,则返回与该组匹配的字符串列表。如果存在多个组,则返回与这些组匹配的字符串元组列表。非捕获组不影响结果的形式。
1. 调用格式
格式 | 参数 | |
|
pattern:编译时使用的表达式字符串 flags:编译标志为。用于修改正则表达式的匹配方式,详见 2.7节 flags修饰符 |
2. 小例子
importrere.findall(r'\bf[a-z]*', 'which foot or hand fell fastest')
Out[]:
[‘foot’, ‘fell’, ‘fastest’]
3.2.7 re.finditer 方法
pattern 在 string 里所有的非重复匹配,返回为一个迭代器 iterator 保存了 匹配对象 。 string 从左到右扫描,匹配按顺序排列。空匹配也包含在结果里。
1. 调用格式
格式 | 参数 | |
|
pattern:编译时使用的表达式字符串 flags:编译标志为。用于修改正则表达式的匹配方式,详见 2.7节 flags修饰符 |
2. 小例子
importre
3.2.8 re.sub 方法
返回通过使用 repl 替换在 string 最左边非重叠出现的 pattern 而获得的字符串。 如果样式没有找到,则不加改变地返回 string。 repl 可以是字符串或函数;如为字符串,则其中任何反斜杠转义序列都会被处理。 也就是说,\n 会被转换为一个换行符,\r 会被转换为一个回车符,依此类推。 未知的 ASCII 字符转义序列保留在未来使用,会被当作错误来处理。 其他未知转义序列例如 & 会保持原样。 向后引用像是 \6 会用样式中第 6 组所匹配到的子字符串来替换。
如果 repl 是一个函数,那它会对每个非重复的 pattern 的情况调用。这个函数只能有一个 匹配对象 参数,并返回一个替换后的字符串。
1. 调用格式
格式 | 参数 | |
|
pattern:编译时使用的表达式字符串 flags:编译标志为。用于修改正则表达式的匹配方式,详见 2.7节 flags修饰符 |
2. 小例子
以下例子来源于Python标准库:
importrere.sub(r'def\s+([a-zA-Z_][a-zA-Z_0-9]*)\s*\(\s*\):', ... r'static PyObject*\npy_\1(void)\n{', ... 'def myfunc():')
Out[]:
‘static PyObject*\npy_myfunc(void)\n{’
def dashrepl(matchobj): if matchobj.group(0) == '-': return ' ' else: return '-' re.sub('-{1,2}', dashrepl, 'pro----gram-files') # 'pro--gram files' re.sub(r'\sAND\s', ' & ', 'Baked Beans And Spam', flags=re.IGNORECASE) # 'Baked Beans & Spam'
3.2.9 re.subn 方法
1. 调用格式
格式 | 参数 | |
|
pattern:编译时使用的表达式字符串 flags:编译标志为。用于修改正则表达式的匹配方式,详见 2.7节 flags修饰符 |
2. 小例子
import re
3.2.10 re.escape 方法
1. 调用格式
格式 | 参数 | |
|
pattern:编译时使用的表达式字符串 |
2. 小例子
以下例子来源于Python标准库:
importreprint(re.escape('https://www.python.org')) # https://www\.python\.orglegal_chars=string.ascii_lowercase+string.digits+"!#$%&'*+-.^_`|~:"print('[%s]+'%re.escape(legal_chars)) # [abcdefghijklmnopqrstuvwxyz0123456789!\#\$%\&'\*\+\-\.\^_`\|\~:]+operators= ['+', '-', '*', '/', '**'] print('|'.join(map(re.escape, sorted(operators, reverse=True)))) /|\-|\+|\*\*|\*
3.2.11 re.purge 方法
调用格式
格式 | 参数 | |
|
无 |