3.3.3 命名分组

捕获分组通常用数字编号来标识,但这样有几个问题:

  1. 数字编号不够直观,虽然规则是“从左到右按照开括号出现的顺序计数”,但括号多了难免混淆
  2. 引用时不够方便,有可能出现二义性

未解决这类问题,一些语言和工具提供了命名分组(named grouping),可已经它看作另一种捕获分组,但是标识是容易记忆和辨别的名字,而不是数字编号。

命名分组的记法并不复杂。在Python中是?P来分组的,其中name是赋予这个分组的名字。使用时再用group(name)来获得对应分组匹配的文本。

例3-32 命名分组捕获

nameRegex = re.compile(r'(?P\d{4})-(?P\d{2})-(?P\d{2})')
result = nameRegex.search('2018-12-17')
print(result.group('year'))  # 2018
print(result.group('month'))  # 12
print(result.group('day'))  # 17

因为数字编号分组的历史更长,为保证向后兼容,即便使用了命名分组,每个分组同时也具有数字编号,其编号规则没有变化。

例3-33 命名分组捕获时仍保留了数字编号

nameRegex = re.compile(r'(?P\d{4})-(?P\d{2})-(?P\d{2})')
result = nameRegex.search('2018-12-17')
print(result.group('year'), result.group(1))  # 2018 2018
print(result.group('month'), result.group(2))  # 12 12
print(result.group('day'), result.group(3))  # 17 17

在Python中,如果使用了命名分组,在表达式中反向引用时,必须使用(?P=name)的记法;而要进行正则表达式替换,则需要写作\g,其中的name是分组的名字。

例3-34 命名分组的引用方法

print(re.search(r'(?P[a-z])(?P=char)', 'aa'))  # 'aa'
print(re.search(r'([a-z])(\1)', 'aa'))  # 'aa'

print(re.sub(r'(?P\d{4})-(?P\d{2})-(?P\d{2})', '\g_\g_\g', '2018-12-17'))  # 17_12_2018

你可能感兴趣的:(3.3.3 命名分组)