Python基础必掌握的正则表达式功能标志用法详解

学Python数据科学,玩游戏、学日语、搞编程一条龙。

整套学习自学教程中应用的数据都是《三國志》、《真·三國無雙》系列游戏中的内容。

对于新手来说正则表达式其实很头疼的,竟让让你怀疑认证怎么能发明出来这么奇怪的东西,其实正则表达式是一个特殊的字符序列,它定义了复杂字符串匹配功能的模式,正则表达式语法需要一点时间来适应。

但是一旦习惯了它,会发现正则表达式在数据处理中几乎是必不可少的。
在这里插入图片描述

Python 中的正则表达式及其用途

1951 年数学家 Stephen Cole Kleene 描述了正则语言的概念,这是一种可以被有限自动机识别并可以使用正则表达式形式表达的语言。在 1960 年代中期,计算机科学先驱 Ken Thompson 是 Unix 的原始设计者之一,他使用 Kleene 的符号在 QED 文本编辑器中实现了模式匹配。

经常我们会遇见需要进行字符串进行查找的业务。

s = 'Dynasty123Warriors'

'123' in s
True

以及字符串查找是否包含和索引位置。

s = 'Dynasty123Warriors'

s.find('123')
3

s.index('123')
3

假设字符串 ‘san123Warriors’、‘Dynasty46san’ 是这样的,为了增加查找效率就会使用到正则表达式。

re 模块功能

re 是 Python 正则表达式功能包,其中包含许多有用的函数和方法。
在这里插入图片描述

re模块中可用的正则表达式函数分三类:搜索功能、替换函数、实用功能。

搜索功能

查找指定正则表达式的一个或多个匹配项。

功能 描述
re.search() 扫描字符串以查找正则表达式匹配
re.match() 在字符串的开头查找正则表达式匹配
re.fullmatch() 查找整个字符串的正则表达式匹配
re.findall() 返回字符串中所有正则表达式匹配的列表
re.finditer() 返回从字符串产生正则表达式匹配的迭代器

re.search(<regex>, <string>, flags=0) ,扫描字符串以查找正则表达式匹配。这里的模式匹配仍然只是逐个字符的比较,与前面显示的 in 运算符和 .find() 示例几乎相同。

re.search(r'(\d+)', 'Dynasty123Warriors')
<_sre.SRE_Match object; span=(3, 6), match='123'>

re.search(r'[a-z]+', '123Dynasty456', flags=re.IGNORECASE)
<_sre.SRE_Match object; span=(3, 6), match='Dynasty'>

print(re.search(r'\d+', 'Dynasty.Warriors'))
None

re.match(<regex>, <string>, flags=0),在字符串的开头查找正则表达式匹配。

re.search(r'\d+', '123DynastyWarriors')
<_sre.SRE_Match object; span=(0, 3), match='123'>

re.search(r'\d+', 'Dynasty123Warriors')
<_sre.SRE_Match object; span=(3, 6), match='123'>

re.match(r'\d+', '123DynastyWarriors')
<_sre.SRE_Match object; span=(0, 3), match='123'>

print(re.match(r'\d+', 'Dynasty123Warriors'))
None

re.fullmatch(<regex>, <string>, flags=0),在整个字符串上查找正则表达式匹配。

print(re.fullmatch(r'\d+', '123Dynasty'))
None

print(re.fullmatch(r'\d+', 'Dynasty123'))
None

print(re.fullmatch(r'\d+', 'Dynasty123Warriors'))
None

re.fullmatch(r'\d+', '123')
<_sre.SRE_Match object; span=(0, 3), match='123'>

re.search(r'^\d+$', '123')
<_sre.SRE_Match object; span=(0, 3), match='123'>

re.findall(<regex>, <string>, flags=0),返回字符串中正则表达式的所有匹配项的列表。

re.findall(r'\w+', '...Dynasty,,,,Warriors:%$dynasty//|')
['Dynasty', 'Warriors', 'dynasty']

re.findall(r'#(\w+)#', '#Dynasty#.#Warriors#.#dynasty#')
['Dynasty', 'Warriors', 'dynasty']

re.findall(r'(\w+),(\w+)', 'Dynasty,Warriors,dynasty,warriors,sanguo,wushuang')
[('Dynasty', 'Warriors'), ('dynasty', 'warriors'), ('sanguo', 'wushuang')]

re.findall(r'(\w+),(\w+),(\w+)', 'Dynasty,Warriors,dynasty,warriors,sanguo,wushuang')
[('Dynasty', 'Warriors', 'dynasty'), ('warriors', 'sanguo', 'wushuang')]

re.finditer(<regex>, <string>, flags=0),返回产生正则表达式匹配的迭代器。

it = re.finditer(r'\w+', '...Dynasty,,,,Warriors:%$dynasty//|')

next(it)
<_sre.SRE_Match object; span=(3, 6), match='Dynasty'>

next(it)
<_sre.SRE_Match object; span=(10, 13), match='Warriors'>

next(it)
<_sre.SRE_Match object; span=(16, 19), match='dynasty'>

next(it)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

for i in re.finditer(r'\w+', '...Dynasty,,,,Warriors:%$dynasty//|'):
    print(i)
<_sre.SRE_Match object; span=(3, 6), match='Dynasty'>
<_sre.SRE_Match object; span=(10, 13), match='Warriors'>
<_sre.SRE_Match object; span=(16, 19), match='dynasty'>

替换函数

功能 描述
re.sub() 扫描字符串以查找正则表达式匹配,用指定的替换字符串替换字符串的匹配部分,并返回结果
re.subn() 行为类似re.sub(),但也返回有关替换次数的信息

re.sub(<regex>, <repl>, <string>, count=0, flags=0),返回对搜索字符串执行替换而产生的新字符串。

# 字符串替换
s = 'Dynasty.123.Warriors.789.dynasty'

re.sub(r'\d+', '#', s)
'Dynasty.#.Warriors.#.dynasty'

re.sub('[a-z]+', '(*)', s)
'(*).123.(*).789.(*)'

# 用相应捕获组的文本替换编号的反向引用 \g<name>
re.sub(r'(\w+),Warriors,dynasty,(\w+)',
       r'\2,Warriors,dynasty,\1',
       'Dynasty,Warriors,dynasty,warriors')
'warriors,Warriors,dynasty,Dynasty'

# 通过在尖括号内指定组号来引用编号反向引用
re.sub(r'Dynasty,(\w+),(\w+),warriors',
       r'Dynasty,\g<2>,\g<1>,warriors',
       'Dynasty,Warriors,dynasty,warriors')
'Dynasty,dynasty,Warriors,warriors'

# <regex>指定零长度匹配,re.sub()则将替换<repl>到字符串中的每个字符位置
re.sub('x*', '-', 'Dynasty')
'-D-y-n-a-s-t-y-'

# 函数替换
def f(match_obj):
    s = match_obj.group(0)  # 匹配字符串
    # s.isdigit() 如果 s 中的所有字符都是数字,则返回 True
    if s.isdigit():
        return str(int(s) * 10)
    else:
        return s.upper()
re.sub(r'\w+', f, 'Dynasty.10.Warriors.20.dynasty.30')
'Dynasty.100.Warriors.200.dynasty.300'

# 限制更换次数
re.sub(r'\w+', 'xxx', 'Dynasty.Warriors.dynasty.warriors')
'xxx.xxx.xxx.xxx'

re.sub(r'\w+', 'xxx', 'Dynasty.Warriors.dynasty.warriors', count=2)
'xxx.xxx.dynasty.warriors'

re.subn(<regex>, <repl>, <string>, count=0, flags=0),返回对搜索字符串执行替换而产生的新字符串,还返回进行的替换次数。

re.subn(r'\w+', 'xxx', 'Dynasty.Warriors.dynasty.warriors')
('xxx.xxx.xxx.xxx', 4)

re.subn(r'\w+', 'xxx', 'Dynasty.Warriors.dynasty.warriors', count=2)
('xxx.xxx.dynasty.warriors', 2)

def f(match_obj):
    m = match_obj.group(0)
    if m.isdigit():
        return str(int(m) * 10)
    else:
        return m.upper()
        
re.subn(r'\w+', f, 'Dynasty.10.Warriors.20.dynasty.30')
('Dynasty.100.Warriors.200.dynasty.300', 6)

实用功能

功能 描述
re.split() 使用正则表达式作为分隔符将字符串拆分为子字符串
re.escape() 转义正则表达式中的字符

re.split(<regex>, <string>, maxsplit=0, flags=0),将字符串拆分为子字符串。

# 指定的字符串拆分为由逗号 ( ,)、分号 ( ;) 或斜线 ( /) 字符分隔的子字符串
re.split('\s*[,;/]\s*', 'Dynasty,Warriors  ;  dynasty / warriors')
['Dynasty', 'Warriors', 'dynasty', 'warriors']

string = 'Dynasty,Warriors  ;  dynasty / warriors'

regex = r'(?:\s*[,;/]\s*)'

re.split(regex, string)
['Dynasty', 'Warriors', 'dynasty', 'warriors']

re.escape(<regex>),转义正则表达式中的字符。

print(re.match('Dynasty^Warriors(dynasty)|warriors', 'Dynasty^Warriors(dynasty)|warriors'))
None

re.match('Dynasty\^Warriors\(dynasty\)\|warriors', 'Dynasty^Warriors(dynasty)|warriors')
<_sre.SRE_Match object; span=(0, 16), match='Dynasty^Warriors(dynasty)|warriors'>

re.escape('Dynasty^Warriors(dynasty)|warriors') == 'Dynasty\^Warriors\(dynasty\)\|warriors'
True

re.match(re.escape('Dynasty^Warriors(dynasty)|warriors'), 'Dynasty^Warriors(dynasty)|warriors')
<_sre.SRE_Match object; span=(0, 16), match='Dynasty^Warriors(dynasty)|warriors'>

正则表达式的标志匹配

标志修改正则表达式解析行为可以进一步细化模式匹配。
在这里插入图片描述
支持的正则表达式标志

简称 原名 作用
re.I re.IGNORECASE 使字母字符的匹配不区分大小写
re.M re.MULTILINE 导致字符串开头和结尾锚点匹配嵌入的换行符
re.S re.DOTALL 使点元字符匹配换行符
re.X re.VERBOSE 允许在正则表达式中包含空格和注释
---- re.DEBUG 使正则表达式解析器向控制台显示调试信息
re.A re.ASCII 为字符分类指定 ASCII 编码
re.U re.UNICODE 为字符分类指定 Unicode 编码
re.L re.LOCALE 根据当前语言环境指定字符分类的编码

匹配不区分大小写模式

re.I 和 re.IGNORECASE

re.search('a+', 'aaaAAA')
<_sre.SRE_Match object; span=(0, 3), match='aaa'>

re.search('A+', 'aaaAAA')
<_sre.SRE_Match object; span=(3, 6), match='AAA'>

re.search('a+', 'aaaAAA', re.I)
<_sre.SRE_Match object; span=(0, 6), match='aaaAAA'>

re.search('A+', 'aaaAAA', re.IGNORECASE)
<_sre.SRE_Match object; span=(0, 6), match='aaaAAA'>

字符串开头和结尾锚点匹配嵌入的换行符

re.M 和 re.MULTILINE

s = 'Dynasty\nWarriors\ndynasty'

re.search('^Dynasty', s)
<_sre.SRE_Match object; span=(0, 3), match='Dynasty'>

print(re.search('^Warriors', s))
None

print(re.search('^dynasty', s))
None

print(re.search('Dynasty$', s))
None

print(re.search('Warriors$', s))
None

re.search('dynasty$', s)
<_sre.SRE_Match object; span=(8, 11), match='dynasty'>

re.search('Dynasty$', s, re.M)
<_sre.SRE_Match object; span=(0, 3), match='Dynasty'>

re.search('Warriors$', s, re.M)
<_sre.SRE_Match object; span=(4, 7), match='Warriors'>

re.search('dynasty$', s, re.M)
<_sre.SRE_Match object; span=(8, 11), match='dynasty'>

使点元字符匹配换行符

re.S 和 re.DOTALL

print(re.search('Dynasty.Warriors', 'Dynasty\nWarriors'))
None

re.search('Dynasty.Warriors', 'Dynasty\nWarriors', re.DOTALL)
<_sre.SRE_Match object; span=(0, 7), match='Dynasty\nWarriors'>

re.search('Dynasty.Warriors', 'Dynasty\nWarriors', re.S)
<_sre.SRE_Match object; span=(0, 7), match='Dynasty\nWarriors'>

允许在正则表达式中包含空格和注释

re.X 和 re.VERBOSE

# 正则表达式包含一个#非转义字符的会忽略右侧全部字符包含自身。
# 电话号码提取的例子
regex = r'^(\(\d{3}\))?\s*\d{4}[-.]\d{4}$'

re.search(regex, '8449.1234')
<_sre.SRE_Match object; span=(0, 9), match='8449.1234'>

re.search(regex, '8449-1234')
<_sre.SRE_Match object; span=(0, 9), match='8449-1234'>

re.search(regex, '(022)8449-1234')
<_sre.SRE_Match object; span=(0, 14), match='(022)8449-1234'>

re.search(regex, '(022) 8449-1234')
<_sre.SRE_Match object; span=(0, 15), match='(022)8449-1234'>

显示调试信息

re.DEBUG

re.search('Dynasty.Warriors', 'DynastyxWarriors', re.DEBUG)
LITERAL 68
LITERAL 121
LITERAL 110
LITERAL 97
LITERAL 115
LITERAL 116
LITERAL 121
ANY None
LITERAL 87
LITERAL 97
LITERAL 114
LITERAL 114
LITERAL 105
LITERAL 111
LITERAL 114
LITERAL 115
<_sre.SRE_Match object; span=(0, 7), match='DynastyxWarriors'>

字符编码解析

指定用于解析特殊正则表达式字符类的字符编码。

"""
re.A / re.ASCII 强制基于 ASCII 编码进行转换。
re.U / re.UNICODE 指定 Unicode 编码。
re.L / re.LOCALE 根据当前语言环境做出判断。

Unicode 联盟创建了 Unicode 来处理这个问题。
Unicode 是一种字符编码标准,旨在代表世界上所有的书写系统。
Python3 中的所有字符串,包括正则表达式,默认都是 Unicode。
"""
# 梵文字符串
s = '\u0967\u096a\u096c'
s
'१४६'

re.search('\d+', s)
<_sre.SRE_Match object; span=(0, 3), match='१४६'>
# 德文字符串
s = 'sch\u00f6n'

s
'schön'

re.search('\w+', s, re.ASCII)
<_sre.SRE_Match object; span=(0, 3), match='sch'>

正则表达式的组合标志

<flags>在函数调用中组合参数,按位 OR ( | ) 运算符组合

re.search('^Warriors', 'Dynasty\nWarriors\ndynasty', re.I|re.M)
<_sre.SRE_Match object; span=(4, 7), match='Warriors'>

在正则表达式中设置和清除标志(?<flags>),在正则表达式的持续时间内设置标志值,a, i, L, m, s, u, 和的一个或多个字母x。

字母 标志
a re.A、re.ASCII
i re.I、re.IGNORECASE
L re.L、re.LOCALE
m re.M、re.MULTILINE
s re.S、re.DOTALL
u re.U、re.UNICODE
x re.X、re.VERBOSE

设置IGNORECASE和MULTILINE标志的等效方法

re.search('^Warriors', 'Dynasty\nWarriors\ndynasty\n', re.I|re.M)
<_sre.SRE_Match object; span=(4, 7), match='Warriors'>

re.search('(?im)^Warriors', 'Dynasty\nWarriors\ndynasty\n')
<_sre.SRE_Match object; span=(4, 7), match='Warriors'>

编译的正则表达式对象

re.compile(<regex>, flags=0),将正则表达式编译为正则表达式对象。

# 正则表达式编译的两种方式
re_obj = re.compile(<regex>, <flags>)
result = re.search(re_obj, <string>)

# 正则表达式编译后调用的方法
re_obj = re.compile(<regex>, <flags>)
result = re_obj.search(<string>)

编译正则表达式的好处

# 一个重复操作繁琐的例子
s1, s2, s3, s4 = 'Dynasty.Warriors', 'Dynasty123Warriors', 'dynasty99', 'warriors & grault'

import re
re.search('\d+', s1)

re.search('\d+', s2)
<_sre.SRE_Match object; span=(3, 6), match='123'>

re.search('\d+', s3)

<_sre.SRE_Match object; span=(3, 5), match='99'>
re.search('\d+', s4)


# 简化编译例1
s1, s2, s3, s4 = 'Dynasty.Warriors', 'Dynasty123Warriors', 'dynasty99', 'warriors & grault'
re_obj = re.compile('\d+')

re_obj.search(s1)

re_obj.search(s2)

<_sre.SRE_Match object; span=(3, 6), match='123'>
re_obj.search(s3)

<_sre.SRE_Match object; span=(3, 5), match='99'>
re_obj.search(s4)


# 简化编译例2
s1, s2, s3, s4 = 'Dynasty.Warriors', 'Dynasty123Warriors', 'dynasty99', 'warriors & grault'
regex = '\d+'

re.search(regex, s1)

re.search(regex, s2)
<_sre.SRE_Match object; span=(3, 6), match='123'>

re.search(regex, s3)
<_sre.SRE_Match object; span=(3, 5), match='99'>

re.search(regex, s4)

正则表达式对象方法

"""
re_obj支持的方法
re_obj.search(<string>[, <pos>[, <endpos>]])
re_obj.match(<string>[, <pos>[, <endpos>]])
re_obj.fullmatch(<string>[, <pos>[, <endpos>]])
re_obj.findall(<string>[, <pos>[, <endpos>]])
re_obj.finditer(<string>[, <pos>[, <endpos>]])
re_obj.split(<string>, maxsplit=0)
re_obj.sub(<repl>, <string>, count=0)
re_obj.subn(<repl>, <string>, count=0)
"""

# 例1
re_obj = re.compile(r'\d+')
s = 'Dynasty123Warriorsdynasty'
re_obj.search(s)
<_sre.SRE_Match object; span=(3, 6), match='123'>

s[6:9]
'Warriors'

print(re_obj.search(s, 6, 9))
None

# 例2
re_obj = re.compile('^Warriors')
s = 'DynastyWarriorsdynasty'
s[3:]
'Warriorsdynasty'

print(re_obj.search(s, 3))
None

正则表达式对象属性

属性 意义
re_obj.flags 任何<flags>对正则表达式有效的
re_obj.groups 正则表达式中的捕获组数
re_obj.groupindex 将构造定义的每个符号组名称(?P<name>)映射到相应组号的字典
re_obj.pattern <regex>产生这个对象的模式

在 re.compile() 调用中指定为 <flags> 值

re_obj = re.compile(r'(?m)(\w+),(\w+)', re.I)

re_obj.flags
42

# 这样表述成 re.I 等价于 42
re_obj = re.compile(r'(?m)(\w+),(\w+)', 42)

re_obj.groups
2

# 正则表示匹配模式
re_obj.pattern
'(?m)(\\w+),(\\w+)'

# 匹配的索引
re_obj = re.compile(r'(?P<w1>),(?P<w2>)')

re_obj.groupindex
mappingproxy({
    
    'w1': 1, 'w2': 2})

re_obj.groupindex['w1']
1

re_obj.groupindex['w2']
2

匹配对象方法和属性

re模块中的大多数函数和方法都会返回一个匹配对象。

m = re.search('Warriors', 'Dynasty.Warriors.dynasty')

m
<_sre.SRE_Match object; span=(4, 7), match='Warriors'>

bool(m)
True

if re.search('Warriors', 'Dynasty.Warriors.dynasty'):
	# <_sre.SRE_Match object; span=(8, 16), match='Warriors'>
	print('有匹配项')
有匹配项

匹配对象方法

属性 返回说明
match.group() 指定的捕获组或组来自match
match.__getitem__() 捕获的组来自match
match.groups() 所有捕获的组来自match
match.groupdict() 命名捕获组的字典来自match
match.expand() 执行反向引用替换的结果match
match.start() 的起始索引match
match.end() 结束索引match
match.span() match作为元组的开始和结束索引

match.group([<group1>, …]),从匹配中返回指定的捕获组。

m = re.search(r'(\w+),(\w+),(\w+)', 'Dynasty,Warriors,dynasty')

m.group(1)
'Dynasty'

m.group(3)
'dynasty'

# 使用 捕获组(?P<name><regex>)
m = re.match(r'(?P<w1>\w+),(?P<w2>\w+),(?P<w3>\w+)','sanguo,wushuang,grault')

m.group('w1')
'sanguo'

m.group('w3')
'grault'

# 捕获组顺序可以指定
m = re.search(r'(\w+),(\w+),(\w+)', 'Dynasty,Warriors,dynasty')

m.group(1, 3)
('Dynasty', 'dynasty')

m.group(3, 3, 1, 1, 2, 2)
('dynasty', 'dynasty', 'Dynasty', 'Dynasty', 'Warriors', 'Warriors')

m = re.match(r'(?P<w1>\w+),(?P<w2>\w+),(?P<w3>\w+)', 'sanguo,wushuang,grault')

m.group('w3', 'w1', 'w1', 'w2')
('grault', 'sanguo', 'sanguo', 'wushuang')

# 超出范围引发异常
m = re.search(r'(\w+),(\w+),(\w+)', 'Dynasty,Warriors,dynasty')

m.group(4)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: no such group

match.__getitem__(<grp>),从匹配中返回捕获的组。

m = re.search(r'(\w+),(\w+),(\w+)', 'Dynasty,Warriors,dynasty')

m.group(2)
'Warriors'

m.__getitem__(2)
'Warriors'

# 返回匹配对象
m = re.search(r'(\w+),(\w+),(\w+)', 'Dynasty,Warriors,dynasty')
m.group(2)
'Warriors'

m.__getitem__(2)
'Warriors'

m[2]
'Warriors'

match.groups(default=None),从匹配中返回所有捕获的组。

# 从匹配中返回所有捕获的组
m = re.search(r'(\w+),(\w+),(\w+)', 'Dynasty,Warriors,dynasty')

m.groups()
('Dynasty', 'Warriors', 'dynasty')

# None可以使用default关键字参数
m = re.search(r'(\w+),(\w+),(\w+)?', 'Dynasty,Warriors,')
m
<_sre.SRE_Match object; span=(0, 8), match='Dynasty,Warriors,'>

print(m.group(3))
None

m.groups()
('Dynasty', 'Warriors', None)

m.groups(default='---')
('Dynasty', 'Warriors', '---')

match.groupdict(default=None),返回命名捕获组的字典。

m = re.match(
	r'Dynasty,(?P<w1>\w+),(?P<w2>\w+),warriors',
	'Dynasty,Warriors,dynasty,warriors')
	
m.groupdict()
{
    
    'w1': 'Warriors', 'w2': 'dynasty'}

m.groupdict()['w2']
'dynasty'

# None可以使用default关键字参数
m = re.match(
	r'Dynasty,(?P<w1>\w+),(?P<w2>\w+)?,warriors',
	'Dynasty,Warriors,,warriors')
m.groupdict()
{
    
    'w1': 'Warriors', 'w2': None}

m.groupdict(default='---')
{
    
    'w1': 'Warriors', 'w2': '---'}

match.expand(<template>),从匹配中执行反向引用替换。

m = re.search(r'(\w+),(\w+),(\w+)', 'Dynasty,Warriors,dynasty')
m
<_sre.SRE_Match object; span=(0, 11), match='Dynasty,Warriors,dynasty'>
m.groups()
('Dynasty', 'Warriors', 'dynasty')

m.expand(r'\2')
'Warriors'

m.expand(r'[\3] -> [\1]')
'[dynasty] -> [Dynasty]'

m = re.search(r'(?P<num>\d+)', 'Dynasty123warriors')
m
<_sre.SRE_Match object; span=(3, 6), match='123'>
m.group(1)
'123'

m.expand(r'--- \g<num> ---')
'--- 123 ---'

match.start([<grp>])、match.end([<grp>]),返回匹配的开始和结束索引。

# 返回匹配的开始和结束索引。
s = 'Dynasty123Warriors456dynasty'

m = re.search('\d+', s)
m
<_sre.SRE_Match object; span=(3, 6), match='123'>

m.start()
3

m.end()
6

m
<_sre.SRE_Match object; span=(3, 6), match='123'>

s[m.start():m.end()]
'123'

match.span(<grp>) = (match.start(<grp>), match.end(<grp>)),返回匹配的开始和结束索引。

s = 'Dynasty123Warriors456dynasty'

m = re.search(r'(\d+)\D*(?P<num>\d+)', s)
m
<_sre.SRE_Match object; span=(3, 12), match='123Warriors456'>

m[0]
'123Warriors456'

m.span()
(3, 12)

m[1]
'123'

m.span(1)
(3, 6)

m['num']
'456'

m.span('num')
(9, 12)

匹配对象属性

属性 说明
match.pos 、match.endpos 匹配的和参数的有效值
match.lastindex 最后捕获的组的索引
match.lastgroup 最后捕获的组的名称
match.re 匹配的编译正则表达式对象
match.string 匹配的搜索字符串

match.pos、match.endpos,<pos>包含搜索和<endpos>搜索的有效值。

re_obj = re.compile(r'\d+')

m = re_obj.search('Dynasty123Warriors', 2, 7)
m
<_sre.SRE_Match object; span=(3, 6), match='123'>

m.pos, m.endpos
(2, 7)

# <pos>和<endpos>参数没有包含在调用中则被省略
re_obj = re.compile(r'\d+')
m = re_obj.search('Dynasty123Warriors')
m
<_sre.SRE_Match object; span=(3, 6), match='123'>

m.pos, m.endpos
(0, 9)

m = re.search(r'\d+', 'Dynasty123Warriors')
m
<_sre.SRE_Match object; span=(3, 6), match='123'>

m.pos, m.endpos
(0, 9)

match.lastindex,包含最后捕获的组的索引。

m = re.search(r'(\w+),(\w+),(\w+)', 'Dynasty,Warriors,dynasty')

m.lastindex
3

m[m.lastindex]
'dynasty'

# 可能不参与的匹配组,返回实际参与匹配的组的数量
m = re.search(r'(\w+),(\w+),(\w+)?', 'Dynasty,Warriors,dynasty')
m.groups()
('Dynasty', 'Warriors', 'dynasty')

m.lastindex, m[m.lastindex]
(3, 'dynasty')

m = re.search(r'(\w+),(\w+),(\w+)?', 'Dynasty,Warriors,')
m.groups()
('Dynasty', 'Warriors', None)

m.lastindex, m[m.lastindex]
(2, 'Warriors')

match.lastgroup,包含最后捕获的组的名称。

s = 'Dynasty123Warriors456dynasty'

m = re.search(r'(?P<n1>\d+)\D*(?P<n2>\d+)', s)
m.lastgroup
'n2'

# 捕获组为空
s = 'Dynasty123Warriors456dynasty'
m = re.search(r'(\d+)\D*(\d+)', s)
m.groups()
('123', '456')

print(m.lastgroup)
None

m = re.search(r'\d+\D*\d+', s)
m.groups()
()

print(m.lastgroup)
None

match.re,包含匹配的正则表达式对象。

regex = r'(\w+),(\w+),(\w+)'

m1 = re.search(regex, 'Dynasty,Warriors,dynasty')
m1

<_sre.SRE_Match object; span=(0, 11), match='Dynasty,Warriors,dynasty'>
m1.re
re.compile('(\\w+),(\\w+),(\\w+)')

re_obj = re.compile(regex)
re_obj
re.compile('(\\w+),(\\w+),(\\w+)')

re_obj is m1.re
True

m2 = re_obj.search('warriors,sanguo,wushuang')
m2
<_sre.SRE_Match object; span=(0, 14), match='warriors,sanguo,wushuang'>

m2.re
re.compile('(\\w+),(\\w+),(\\w+)')

m2.re is re_obj is m1.re
True

# 可以访问匹配的正则表达式对象的所有属性也都可用
m1.re.groups
3

m1.re.pattern
'(\\w+),(\\w+),(\\w+)'

m1.re.pattern == regex
True

m1.re.flags
32

match.string,包含匹配的搜索字符串。

m = re.search(r'(\w+),(\w+),(\w+)', 'Dynasty,Warriors,dynasty')

m.string
'Dynasty,Warriors,dynasty'

re_obj = re.compile(r'(\w+),(\w+),(\w+)')
m = re_obj.search('Dynasty,Warriors,dynasty')
m.string
'Dynasty,Warriors,dynasty'

猜你喜欢

转载自blog.csdn.net/qq_20288327/article/details/124536144