目录
r:Python 中字符串的前导 r
代表原始字符串标识符,该字符串中的特殊符号不会被转义,适用于正则表达式中繁杂的特殊符号表示。 因此 r"\n"
表示包含 '\'
和 'n'
两个字符的字符串,而 "\n"
则表示只包含一个换行符的字符串。
标志
在 3.6 版本发生变更: 标志常量现在是 RegexFlag 类的实例,这个类是 enum.IntFlag 的子类。
class re.RegexFlag
包含以下列出的正则表达式选项的 enum.IntFlag 类。
Added in version 3.11: - added to
__all__
re.A / re.ASCII
使 \w
, \W
, \b
, \B
, \d
, \D
, \s
和 \S
执行仅限 ASCII 匹配而不是完整的 Unicode 匹配。 这仅对 Unicode (str) 模式有意义,而对字节串模式将被忽略。
对应于内联旗标 (?a)
。
备注:
U 旗标仍然存在以保持下向兼容性,但在 Python 3 中是多余的因为对于
str
模式默认使用 Unicode,并且 Unicode 匹配对于 bytes 模式则是不允许的。 UNICODE 和内联旗标(?u)
同样也是多余的。
re.DEBUG
显示有关被编译表达式的调试信息。
没有对应的内联旗标。
re.I / re.IGNORECASE
执行忽略大小写的匹配;[A-Z]
这样的表达式也将匹配小写字母。 完全的 Unicode 匹配 (如 Ü
将匹配 ü
) 同样适用,除非使用了 ASCII 旗标来禁用非 ASCII 匹配。 当前语言区域不会改变该旗标的效果,除非还使用了 LOCALE 旗标。
对应于内联旗标 (?i)
。
请注意当 Unicode 模式 [a-z]
或 [A-Z]
与 IGNORECASE 旗标一起使用时,它们将匹配 52 个 ASCII 字母和 4 个额外的非 ASCII 字母: 'İ' (U+0130, 大写拉丁字母 I 带有上方的点), 'ı' (U+0131, 小写拉丁字母 i 不带上方的点), 'ſ' (U+017F, 小写拉丁字母长 s) 和 'K' (U+212A, 开尔文标记)。 如果使用了 ASCII 旗标,则只匹配字母 'a' 到 'z' 和 'A' 到 'Z'。
re.L / re.LOCALE
使 \w
, \W
, \b
, \B
和忽略大小写的匹配依赖于当前语言区域。 该旗标仅适用于 bytes 模式。
对应于内联旗标 (?L)
。
警告: 该旗标已不建议使用;请考虑改用 Unicode 匹配。 语言区域机制相当不可靠因为它每次只能处理一种“文化”并且只适用于 8 位语言区域。 Unicode (str) 模式默认启用 Unicode 匹配并且能够处理不同的语言区域和语言。
在 3.6 版本发生变更: LOCALE 仅适用于 bytes 模式并且不能兼容 ASCII。
在 3.7 版本发生变更: 设置了 LOCALE 旗标的已编译正则表达式对象不会再依赖于编译时的语言区域。 只有在匹配时的语言区域才会影响匹配结果。
re.M / re.MULTILINE
在指定之后,模式字符 '^'
将匹配字符串的开始和每一行的开头(紧随在换行符之后);而模式字符 '$'
将匹配字符串的末尾和每一行的末尾(紧接在换行符之前)。 在默认情况下,'^'
只匹配字符串的开头,而``'$'`` 只匹配字符串的末尾和紧接在字符串末尾(可能存在的)换行符之前。
对应于内联旗标 (?m)
。
re.NOFLAG
表示未应用任何旗标,该值为 0
。 该旗标可被用作某个函数关键字参数的默认值或者用作将与其他旗标进行有条件 OR 运算的基准值。 用作默认值的例子:
def myfunc(text, flag=re.NOFLAG):
return re.match(text, flag)
Added in version 3.11.
re.S / re.DOTALL
使 '.'
特殊字符匹配任意字符,包括换行符;如果没有这个旗标,'.'
将匹配 除去 换行符以外的任意字符。
对应于内联旗标 (?s)
。
re.U / re.UNICODE
在 Python 3 中,str
模式默认将匹配 Unicode 字符。 因此这个旗标多余且 无任何效果,仅保留用于向下兼容。
请参阅 ASCII 了解如何改为仅限匹配 ASCII 字符。
re.X / re.VERBOSE
这个旗标允许你通过在视觉上分隔表达式的逻辑段落和添加注释来编写更为友好并更具可读性的正则表达式。 表达式中的空白符会被忽略,除非是在字符类中,或前面有一个未转义的反斜杠,或者是在 *?
, (?:
或 (?P<...>
等形符之内。 例如,(? :
和 * ?
是不被允许的。 当一个行内包含不在字符类中并且前面没有未转义反斜杠的 #
时,则从最左边的此 #
直至行尾的所有字符都会被忽略。
意思就是下面两个正则表达式等价地匹配一个十进制数字:
a = re.compile(r"""\d + # the integral part
\. # the decimal point
\d * # some fractional digits""", re.X)
b = re.compile(r"\d+\.\d*")
对应内联标记 (?x)
。
函数
pattern | 匹配的正则表达式 |
string | 要匹配的字符串 |
flags | 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。
|
re.compile函数
语法:re.compile(pattern, flags=0)
将正则表达式的样式编译为一个 正则表达式对象 (正则对象),可以用于匹配,通过这个对象的方法 match(), search() 以及其他如下描述。
表达式的行为可通过指定 flags 值来修改。 值可以是任意 flags 变量,可使用按位 OR (|
运算符) 进行组合。
prog = re.compile(pattern)
result = prog.match(string)
#等价于
result = re.match(pattern, string)
如果需要多次使用这个正则表达式的话,使用 re.compile() 和保存这个正则对象以便复用,可以让程序更加高效。
备注:通过 re.compile() 编译后的样式,和模块级的函数会被缓存, 所以少数的正则表达式使用无需考虑编译的问题。
>>>import re
>>> pattern = re.compile(r'\d+')
m = pattern.match('one12twothree34four', 3, 10) # 从'1'的位置开始匹配,正好匹配
>>> print m # 返回一个 Match 对象
<_sre.SRE_Match object at 0x10a42aac0>
>>> m.group(0) # 可省略 0
'12'
>>> m.start(0) # 可省略 0
3
>>> m.end(0) # 可省略 0
5
>>> m.span(0) # 可省略 0
(3, 5)
在上面,当匹配成功时返回一个 Match 对象,其中:
- group([group1, …]) 方法用于获得一个或多个分组匹配的字符串,当要获得整个匹配的子串时,可直接使用 group() 或 group(0);
- start([group]) 方法用于获取分组匹配的子串在整个字符串中的起始位置(子串第一个字符的索引),参数默认值为 0;
- end([group]) 方法用于获取分组匹配的子串在整个字符串中的结束位置(子串最后一个字符的索引+1),参数默认值为 0;
- span([group]) 方法返回 (start(group), end(group))
re.search函数
语法:re.search(pattern, string, flags=0)
扫描整个 string 查找正则表达式 pattern 产生匹配的第一个位置,并返回相应的 Match。 如果字符串中没有与模式匹配的位置则返回 None
;请注意这不同于在字符串的某个位置上找到零长度匹配。
import re
ret = re.search(r"\d+", "阅读次数为9999")
print(ret.group())
#结果:
#9999
re.match函数
语法:re.match(pattern, string, flags=0)
尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。匹配成功re.match方法返回一个匹配的对象。
如果上⼀步匹配到数据的话,可以使⽤group⽅法来提取数据。以使用group(num) 或 groups() 匹配对象函数来获取匹配表达式。
group()用来提出分组截获的字符串,()用来分组,group() 同group(0)就是匹配正则表达式整体结果,group(1) 列出第一个括号匹配部分,group(2) 列出第二个括号匹配部分,group(3) 列出第三个括号匹配部分。没有匹配成功的,re.search()返回None。
>>> import re
>>> result = re.match("itcast","itcast.cn")
>>> result.group()
'itcast'
从string头开始匹配pattern完全可以匹配,pattern匹配结束,同时匹配终止,后面的.cn不再匹配,返回匹配成功的信息。
注意即便是 MULTILINE 多行模式, re.match() 也只匹配字符串的开始位置,而不匹配每行开始。
如果你想定位 string 的任何位置,使用 search() 来替代(也可参考 search() vs. match() )
re.match与re.search的区别:re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配。
re.fullmatch函数
语法:re.fullmatch(pattern, string, flags=0)
如果整个 string 与正则表达式 pattern 匹配,则返回相应的 Match。 如果字符串与模式不匹配则返回 None
;请注意这与零长度匹配是不同的。
Added in version 3.4.
re.split函数
语法:re.split(pattern, string, maxsplit=0, flags=0)
用 pattern 分开 string 。 如果在 pattern 中捕获到括号,那么所有的组里的文字也会包含在列表里。如果 maxsplit 非零, 最多进行 maxsplit 次分隔, 剩下的字符全部返回到列表的最后一个元素。
>>> re.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.1 版本发生变更: 增加了可选标记参数。
在 3.7 版本发生变更: 增加了空字符串的样式分隔。
re.findall函数
语法:re.findall(pattern, string, flags=0)
返回 pattern 在 string 中的所有非重叠匹配,以字符串列表或字符串元组列表的形式。对 string 的扫描从左至右,匹配结果按照找到的顺序返回。 空匹配也包括在结果中。
返回结果取决于模式中捕获组的数量。如果没有组,返回与整个模式匹配的字符串列表。如果有且仅有一个组,返回与该组匹配的字符串列表。如果有多个组,返回与这些组匹配的字符串元组列表。非捕获组不影响结果。
>>> re.findall(r'\bf[a-z]*', 'which foot or hand fell fastest')
['foot', 'fell', 'fastest']
>>> re.findall(r'(\w+)=(\d+)', 'set width=20 and height=10')
[('width', '20'), ('height', '10')]
在 3.7 版本发生变更: 非空匹配现在可以在前一个空匹配之后出现了。
re.finditer函数
语法:re.finditer(pattern, string, flags=0)
针对正则表达式 pattern 在 string 里的所有非重叠匹配返回一个产生 Match 对象的 iterator。 string 将被从左至右地扫描,并且匹配也将按被找到的顺序返回。 空匹配也会被包括在结果中。
和 findall 类似,在字符串中找到正则表达式所匹配的所有子串,并把它们作为一个迭代器返回。
import re
it = re.finditer(r"\d+", "12a32bc43jf3")
for match in it:
print(match.group())
#结果:
#12
#32
#43
#3
在 3.7 版本发生变更: 非空匹配现在可以在前一个空匹配之后出现了。
re.sub函数
语法:re.sub(pattern, repl, string, count=0, flags=0)
pattern | 必选,表示正则中的模式字符串 |
repl | 必选,就是replacement,要替换的字符串,也可为一个函数 |
string | 必选,被替换的那个string字符串 |
count | 可选参数,count 是要替换的最大次数,必须是非负整数。如果省略这个参数或设为 0,所有的匹配都会被替换 |
flags | 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。
|
返回通过使用 repl 替换在 string 最左边非重叠出现的 pattern 而获得的字符串。 如果样式没有找到,则不加改变地返回 string。 repl 可以是字符串或函数;如为字符串,则其中任何反斜杠转义序列都会被处理。 也就是说,\n
会被转换为一个换行符,\r
会被转换为一个回车符,依此类推。 未知的 ASCII 字符转义序列保留在未来使用,会被当作错误来处理。 其他未知转义序列例如 \&
会保持原样。 向后引用像是 \6
会用样式中第 6 组所匹配到的子字符串来替换。 例如:
>>> re.sub(r'def\s+([a-zA-Z_][a-zA-Z_0-9]*)\s*\(\s*\):',
... r'static PyObject*\npy_\1(void)\n{',
... 'def myfunc():')
'static PyObject*\npy_myfunc(void)\n{'
import re
ret = re.sub(r"\d+", '998', "python = 997")
print(ret)
#结果:python = 998
如果 repl 是一个函数,则它会针对每次 pattern 的非重叠出现的情况被调用。 该函数接受单个 Match 参数,并返回替换字符串。 例如:
>>> 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'
import re
def add(temp):
#int()参数必须是字符串,类似字节的对象或数字,而不是“re.Match”
strNum = temp.group()
num = int(strNum) + 1
return str(num)
ret = re.sub(r"\d+", add, "python = 997")
print(ret)
ret = re.sub(r"\d+", add, "python = 99")
print(ret)
#结果:
#python = 998
#python = 100
模式可以是一个字符串或者 Pattern。
可选参数 count 是要替换的最大次数;count 必须是非负整数。如果省略这个参数或设为 0,所有的匹配都会被替换。 样式的空匹配仅在与前一个空匹配不相邻时才会被替换,所以 sub('x*', '-', 'abxd')
返回 '-a-b--d-'
。
在字符串类型的 repl 参数里,如上所述的转义和向后引用中,\g<name>
会使用命名组合 name
,(在 (?P<name>…)
语法中定义) \g<number>
会使用数字组;\g<2>
就是 \2
,但它避免了二义性,如 \g<2>0
。 \20
就会被解释为组20,而不是组2后面跟随一个字符 '0'
。向后引用 \g<0>
把 pattern 作为一整个组进行引用。
在 3.1 版本发生变更: 增加了可选标记参数。
在 3.5 版本发生变更: 不匹配的组合替换为空字符串。
在 3.6 版本发生变更: pattern 中的未知转义(由
'\'
和一个 ASCII 字符组成)被视为错误。在 3.7 版本发生变更: Unknown escapes in repl consisting of
'\'
and an ASCII letter now are errors.在 3.7 版本发生变更: Empty matches for the pattern are replaced when adjacent to a previous non-empty match.
在 3.12 版本发生变更: 分组 id 只能包含 ASCII 数码。 在 bytes 替换字符串中,分组 name 只能包含 ASCII 范围内的字节值 (
b'\x00'
-b'\x7f'
)。
re.subn函数
语法:re.subn(pattern, repl, string, count=0, flags=0)
行为与 sub() 相同,但是返回一个元组 (字符串, 替换次数),即
(sub(repl, string[, count]), 替换次数)。
import re
pattern = re.compile(r'(\w+) (\w+)')
s = 'i say, hello world!'
print(re.subn(pattern, r'\2 \1', s))
def func(m):
return m.group(1).title() + ' ' + m.group(2).title()
print(re.subn(pattern, func, s))
### output ###
# ('say i, world hello!', 2)
# ('I Say, Hello World!', 2)
在 3.1 版本发生变更: 增加了可选标记参数。
在 3.5 版本发生变更: 不匹配的组合替换为空字符串。
re.escape函数
语法:re.escape(pattern)
转义 pattern 中的特殊字符。如果你想对任意可能包含正则表达式元字符的文本字符串进行匹配,它就是有用的。比如
>>> print(re.escape('https://www.python.org'))
https://www\.python\.org
>>> legal_chars = string.ascii_lowercase + string.digits + "!#$%&'*+-.^_`|~:"
>>> print('[%s]+' % re.escape(legal_chars))
[abcdefghijklmnopqrstuvwxyz0123456789!\#\$%\&'\*\+\-\.\^_`\|\~:]+
>>> operators = ['+', '-', '*', '/', '**']
>>> print('|'.join(map(re.escape, sorted(operators, reverse=True))))
/|\-|\+|\*\*|\*
这个函数不能被用于 sub() 和 subn() 的替换字符串,只有反斜杠应该被转义。 例如:
>>> digits_re = r'\d+'
>>> sample = '/usr/sbin/sendmail - 0 errors, 12 warnings'
>>> print(re.sub(digits_re, digits_re.replace('\\', r'\\'), sample))
/usr/sbin/sendmail - \d+ errors, \d+ warnings
在 3.3 版本发生变更:
'_'
不再被转义。在 3.7 版本发生变更: 只有在正则表达式中具有特殊含义的字符才会被转义。 因此,
'!'
,'"'
,'%'
,"'"
,','
,'/'
,':'
,';'
,'<'
,'='
,'>'
,'@'
和"`"
将不再会被转义。
re.purge函数
语法:re.purge()
清除正则表达式的缓存。
python贪婪和⾮贪婪
Python⾥数量词默认是贪婪的(在少数语⾔⾥也可能是默认⾮贪婪),总是尝试匹配尽可能多的字符;⾮贪婪则相反,总是尝试匹配尽可能少的字符。
例如:正则表达式”ab*”如果用于查找”abbbc”,将找到”abbb”。而如果使用非贪婪的数量词”ab*?”,将找到”a”。
注:我们一般使用非贪婪模式来提取。
在"*","?","+","{m,n}"后⾯加上?,使贪婪变成⾮贪婪。
import re
s="This is a number 234-235-22-423"
#正则表达式模式中使⽤到通配字,那它在从左到右的顺序求值时,会尽量“抓取”满⾜匹配最⻓字符串,在我们上⾯的例⼦⾥⾯,“.+”会从字符串的启始处抓取满⾜模式的最⻓字符,其中包括我们想得到的第⼀个整型字段的中的⼤部分,“\d+”只需⼀位字符就可以匹配,所以它匹配了数字“4”,⽽“.+”则匹配了从字符串起始到这个第⼀位数字4之前的所有字符
r=re.match(".+(\d+-\d+-\d+-\d+)",s)
print(r.group(1))
#⾮贪婪操作符“?”,这个操作符可以⽤在"*","+","?"的后⾯,要求正则匹配的越少越好
r=re.match(".+?(\d+-\d+-\d+-\d+)",s)
print(r.group(1))
#结果:
#4-235-22-423
#234-235-22-423
>>> re.match(r"aa(\d+)","aa2343ddd").group(1)
'2343'
>>> re.match(r"aa(\d+?)","aa2343ddd").group(1)
'2'
>>> re.match(r"aa(\d+)ddd","aa2343ddd").group(1)
'2343'
>>> re.match(r"aa(\d+?)ddd","aa2343ddd").group(1)
'2343'
import re
test_str="<img data-original=https://rpic.douyucdn.cn/appCovers/2016/11/13/1213973.jpg>"
ret = re.search(r"https://.*?.jpg", test_str)
print(ret.group())
#结果:https://rpic.douyucdn.cn/appCovers/2016/11/13/1213973.jpg
正则表达式对象 (正则对象)
class re.Pattern
由 re.compile() 返回的已编译正则表达式对象。
在 3.9 版本发生变更: re.Pattern 支持用
[]
表示 Unicode (str) 或字节串类型的模式。 参见 GenericAlias 类型。
Pattern.search函数
语法:Pattern.search(string[, pos[, endpos]])
扫描整个 string 查找该正则表达式产生匹配的第一个位置,并返回相应的 Match。 如果字符串中没有与模式匹配的位置则返回 None
;请注意这不同于在字符串的某个位置上找到零长度匹配。
可选的第二个参数 pos 给出了字符串中开始搜索的位置索引;默认为 0
,它不完全等价于字符串切片; '^'
样式字符匹配字符串真正的开头,和换行符后面的第一个字符,但不会匹配索引规定开始的位置。
可选参数 endpos 限定了字符串搜索的结束;它假定字符串长度到 endpos , 所以只有从 pos
到 endpos - 1
的字符会被匹配。如果 endpos 小于 pos,就不会有匹配产生;另外,如果 rx 是一个编译后的正则对象, rx.search(string, 0, 50)
等价于 rx.search(string[:50], 0)
。
>>> pattern = re.compile("d")
>>> pattern.search("dog") # Match at index 0
<re.Match object; span=(0, 1), match='d'>
>>> pattern.search("dog", 1) # No match; search doesn't include the "d"
Pattern.match函数
语法:Pattern.match(string[, pos[, endpos]])
如果字符串 开头 的零个或多个字符与此正则表达式匹配,则返回相应的 Match。 如果字符串与模式不匹配则返回 None
;请注意这与零长度匹配是不同的。
可选参数 pos 和 endpos 与 search() 含义相同。
>>> pattern = re.compile("o")
>>> pattern.match("dog") # No match as "o" is not at the start of "dog".
>>> pattern.match("dog", 1) # Match as "o" is the 2nd character of "dog".
<re.Match object; span=(1, 2), match='o'>
如果你想定位匹配在 string 中的位置,使用 search() 来替代(另参考 search() vs. match())。
Pattern.fullmatch函数
语法:Pattern.fullmatch(string[, pos[, endpos]])
如果整个 string 与此正则表达式匹配,则返回相应的 Match。 如果字符串与模式不匹配则返回 None
;请注意这与零长度匹配是不同的。
可选参数 pos 和 endpos 与 search() 含义相同。
>>> pattern = re.compile("o[gh]")
>>> pattern.fullmatch("dog") # No match as "o" is not at the start of "dog".
>>> pattern.fullmatch("ogre") # No match as not the full string matches.
>>> pattern.fullmatch("doggie", 1, 3) # Matches within given limits.
<re.Match object; span=(1, 3), match='og'>
Added in version 3.4.
Pattern.split函数
语法:Pattern.split(string, maxsplit=0)
等价于 split() 函数,使用了编译后的样式。
Pattern.findall函数
语法:Pattern.findall(string[, pos[, endpos]])
类似函数 findall() , 使用了编译后样式,但也可以接收可选参数 pos 和 endpos ,限制搜索范围,就像 search()。
Pattern.finditer函数
语法:Pattern.finditer(string[, pos[, endpos]])
类似函数 finditer() , 使用了编译后样式,但也可以接收可选参数 pos 和 endpos ,限制搜索范围,就像 search()。
Pattern.sub函数
语法:Pattern.sub(repl, string, count=0)
等价于 sub() 函数,使用了编译后的样式。
Pattern.subn函数
语法:Pattern.subn(repl, string, count=0)
等价于 subn() 函数,使用了编译后的样式。
Pattern.flags
正则表达式匹配旗标。 这是一个传给 compile() 的旗标组合,模式中的任何 (?...)
内联旗标,以及隐式旗标如当模式为 Unicode 字符串时的 UNICODE。
Pattern.groups
捕获到的模式串中组的数量。
Pattern.groupindex
映射由 (?P<id>)
定义的命名符号组合和数字组合的字典。如果没有符号组,那字典就是空的。
Pattern.pattern
编译对象的原始样式字符串。
在 3.7 版本发生变更: 添加 copy.copy() 和 copy.deepcopy() 函数的支持。编译后的正则表达式对象被认为是原子性的。
匹配对象
匹配对象总是有一个布尔值 True
。如果没有匹配的话 match() 和 search() 返回 None
所以你可以简单的用 if
语句来判断是否匹配
match = re.search(pattern, string)
if match:
process(match)
class re.Match
由成功的 match
和 search
所返回的匹配对象。
在 3.9 版本发生变更: re.Match 支持用
[]
表示 Unicode (str) 或字节串类型的匹配。 参见 GenericAlias 类型。
Match.expand函数
语法:Match.expand(template)
返回通过在模板字符串 template 上执行反斜杠替换所获得的字符串,就像 sub() 方法所做的那样。 转义符例如 \n
将被转换为适当的字符,而数字反向引用 (\1
, \2
) 和命名反向引用 (\g<1>
, \g<name>
) 将被替换为相应分组的内容。 反向引用 \g<0>
将被替换为整个匹配的内容。
在 3.5 版本发生变更: 不匹配的组合替换为空字符串。
Match.group函数
语法:Match.group([group1, ...])
返回一个或者多个匹配的子组。如果只有一个参数,结果就是一个字符串,如果有多个参数,结果就是一个元组(每个参数对应一个项),如果没有参数,组1默认到0(整个匹配都被返回)。 如果一个组N 参数值为 0,相应的返回值就是整个匹配字符串;如果它是一个范围 [1..99],结果就是相应的括号组字符串。如果一个组号是负数,或者大于样式中定义的组数,就引发一个 IndexError 异常。如果一个组包含在样式的一部分,并被匹配多次,就返回最后一个匹配。:
>>> m = re.match(r"(\w+) (\w+)", "Isaac Newton, physicist")
>>> m.group(0) # The entire match
'Isaac Newton'
>>> m.group(1) # The first parenthesized subgroup.
'Isaac'
>>> m.group(2) # The second parenthesized subgroup.
'Newton'
>>> m.group(1, 2) # Multiple arguments give us a tuple.
('Isaac', 'Newton')
如果正则表达式使用了 (?P<name>...)
语法, groupN 参数就也可能是命名组合的名字。如果一个字符串参数在样式中未定义为组合名,就引发一个 IndexError 异常。
一个相对复杂的例子
>>> m = re.match(r"(?P<first_name>\w+) (?P<last_name>\w+)", "Malcolm Reynolds")
>>> m.group('first_name')
'Malcolm'
>>> m.group('last_name')
'Reynolds'
命名组合同样可以通过索引值引用
>>> m.group(1)
'Malcolm'
>>> m.group(2)
'Reynolds'
如果一个组匹配成功多次,就只返回最后一个匹配
>>> m = re.match(r"(..)+", "a1b2c3") # Matches 3 times.
>>> m.group(1) # Returns only the last match.
'c3'
Match.__getitem__函数
语法:Match.__getitem__(g)
这个等价于 m.group(g)
。这允许更方便的引用一个匹配
>>> m = re.match(r"(\w+) (\w+)", "Isaac Newton, physicist")
>>> m[0] # The entire match
'Isaac Newton'
>>> m[1] # The first parenthesized subgroup.
'Isaac'
>>> m[2] # The second parenthesized subgroup.
'Newton'
命名分组也是受支持的:
>>> m = re.match(r"(?P<first_name>\w+) (?P<last_name>\w+)", "Isaac Newton")
>>> m['first_name']
'Isaac'
>>> m['last_name']
'Newton'
Added in version 3.6.
Match.groups函数
语法:Match.groups(default=None)
返回一个元组,包含所有匹配的子组,在样式中出现的从1到任意多的组合。 default 参数用于不参与匹配的情况,默认为 None
。
例如:
>>> m = re.match(r"(\d+)\.(\d+)", "24.1632")
>>> m.groups()
('24', '1632')
如果我们使小数点可选,那么不是所有的组都会参与到匹配当中。这些组合默认会返回一个 None
,除非指定了 default 参数。
>>> m = re.match(r"(\d+)\.?(\d+)?", "24")
>>> m.groups() # Second group defaults to None.
('24', None)
>>> m.groups('0') # Now, the second group defaults to '0'.
('24', '0')
Match.groupdict函数
语法:Match.groupdict(default=None)
返回一个字典,包含了所有的 命名 子组。key就是组名。 default 参数用于不参与匹配的组合;默认为 None
。 例如
>>> m = re.match(r"(?P<first_name>\w+) (?P<last_name>\w+)", "Malcolm Reynolds")
>>> m.groupdict()
{'first_name': 'Malcolm', 'last_name': 'Reynolds'}
Match.start和Match.end函数
语法:Match.start([group])
语法:Match.end([group])
返回 group 匹配到的字串的开始和结束标号。group 默认为0(意思是整个匹配的子串)。如果 group 存在,但未产生匹配,就返回 -1
。对于一个匹配对象 m, 和一个未参与匹配的组 g ,组 g (等价于 m.group(g)
)产生的匹配是
m.string[m.start(g):m.end(g)]
注意 m.start(group)
将会等于 m.end(group)
,如果 group 匹配一个空字符串的话。比如,在 m = re.search('b(c?)', 'cba')
之后,m.start(0)
为 1, m.end(0)
为 2, m.start(1)
和 m.end(1)
都是 2, m.start(2)
引发一个 IndexError 异常。
这个例子会从email地址中移除掉 remove_this
>>> email = "tony@tiremove_thisger.net"
>>> m = re.search("remove_this", email)
>>> email[:m.start()] + email[m.end():]
'tony@tiger.net'
Match.span函数
语法:Match.span([group])
对于一个匹配 m , 返回一个二元组 (m.start(group), m.end(group))
。 注意如果 group 没有在这个匹配中,就返回 (-1, -1)
。group 默认为0,就是整个匹配。
Match.pos
pos 的值,会传递给 search() 或 match() 的方法 a 正则对象 。这个是正则引擎开始在字符串搜索一个匹配的索引位置。
Match.endpos
endpos 的值,会传递给 search() 或 match() 的方法 a 正则对象 。这个是正则引擎停止在字符串搜索一个匹配的索引位置。
Match.lastindex
捕获组的最后一个匹配的整数索引值,或者 None
如果没有匹配产生的话。比如,对于字符串 'ab'
,表达式 (a)b
, ((a)(b))
, 和 ((ab))
将得到 lastindex == 1
, 而 (a)(b)
会得到 lastindex == 2
。
Match.lastgroup
最后一个匹配的命名组名字,或者 None
如果没有产生匹配的话。
Match.re
返回产生这个实例的 正则对象 , 这个实例是由 正则对象的 match() 或 search() 方法产生的。
Match.string
在 3.7 版本发生变更: 添加了对 copy.copy() 和 copy.deepcopy() 的支持。匹配对象被看作是原子性的。