命名捕获组
命令组的语法是 Python 专用扩展之一,格式是 (?p…),其中 name 是组的名称,…是要匹配的表达式,除了该组有个名字之外,命名组也同捕获组是相同的。它们的行为与正常组完全相同,除了可以通过索引访问还可以通过 group(name) 方式访问它们。非捕获组的格式是 (?:…)。
MatchObject` 的方法处理捕获组时接受的要么是表示组号的整数,要么是包含组名的字符串。命名组也可以是数字,所以你可以通过两种方式来得到一个组的信息:
import re
pattern = r"(?P<python>123)(?:456)(789)"
string = "123456789"
match = re.match(pattern,string)
if match:
print(match.group("python"))
print(match.group(1))
print(match.groups())
123
123
('123', '789')
命名组是便于使用的,因为它可以让你使用容易记住的名字来代替不得不记住的数字
InternalDate = re.compile(r'INTERNALDATE "'
r'(?P<day>[ 123][0-9])-(?P<mon>[A-Z][a-z][a-z])-'
r'(?P<year>[0-9][0-9][0-9][0-9])'
r'(?P<hour>[0-9][0-9]):(?P<min>[0-9][0-9]):(?P<sec>[0-9][0-9])'
r'(?P<zonen>[-+])(?P<zoneh>[0-9][0-9])(?P<zonem>[0-9][0-9])'
r'"')
很明显,得到 m.group(‘zonem’) 要比记住得到组 9 要容易得多
因为逆向引用的语法,象 (…)\1 这样的表达式所表示的是组号,这时用组名代替组号自然会有差别。
还有一个 Python 扩展:(?P=name) ,它可以使叫 name 的组内容再次在当前位置发现。正则表达式为了找到重复的单词,(\b\w+)\s+\1 也可以被写成 (?P\b\w+)\s+(?P=word):
>>> p = re.compile(r'(?P<word>\b\w+)\s+(?P=word)')
>>> p.search('Paris in the the spring').group()
'the the'
非捕获组
非捕获组值匹配结果,但不捕获结果,也不会分配组号,当然也不能在表达式和程序中做进一步处理。
import re
pattern = r"(?P<python>123)(?:456)(789)"
string = "123456789"
match = re.match(pattern,string)
if match:
print(match.group("python"))#123
print(match.groups())#('123', '789')
- (?:pattern) : 匹配pattern,但不捕获匹配结果
s="industryOpqindustries"
res=re.findall("industr(?:y|ies)",s)
print(res)#['industry', 'industries']
- (?=pattern): 零宽度正向预查(正向零宽断言),匹配后面跟的是pattern的内容,不匹配pattern,也不捕获匹配结果。
s="windows2019windows2018windows1989"
res=re.sub("windows(?=2018|1989)","microsoft",s)
print(res)#windows2019microsoft2018microsoft1989
- (?!pattern): 零宽度负向预查(负向零宽断言),匹配后面跟的不是pattern的内容,不匹配pattern,不捕获匹配结果。
res=re.sub("windows(?!2018|1989)","microsoft",s)
print(res)#microsoft2019windows2018windows1989
- (?<=pattern): 零宽度正向回查(正向零宽断言),匹配前面是pattern的内容,不匹配pattern,不捕获匹配结果。
s="windows2019microfost2019"
res=re.sub("(?<=microfost)2019","pattern",s)
print(res)#windows2019microfostpattern
- (?<!pattern): 零宽度负向回查(负向零宽断言),匹配前面不是pattern的内容,不匹配pattern,不捕获匹配结果。
res=re.sub("(?<!microfost)2019","pattern",s)
print(res)#windowspatternmicrofost2019