08-利用括号分组
7.3.1 利用括号分组
假定想要将区号从电话号码中分离,添加括号将在正则表达式中创建“分组”: (\d\d\d)-(\d\d\d-\d\d\d\d)
。然后可以使用 group()
匹配对象方法,从一个分组中获取匹配的文本。
正则表达式字符串中的第一对括号是第 1 组,第二对括号是第 2 组。向 group()
匹配对象方法传入整数 1 或 2,就可以取得匹配文本的不同部分。向 group()
方法传入0或不传入参数,将返回整个匹配的文本。在交互式环境中输入以下代码:
>>> phoneNumRegex = re.compile(r'(\d\d\d)-(\d\d\d-\d\d\d\d)')
>>> mo = phoneNumRegex.search('My number is 415-555-4242.')
>>> mo.group(1)
'415'
>>> mo.group(2)
'555-4242'
>>> mo.group(0)
'415-555-4242'
>>> mo.group()
'415-555-4242'
如果想要一次就获取所有的分组,请使用 groups()
方法,注意函数名的复数形式:
>>> mo.groups()
('415', '555-4242')
>>> areaCode, mainNumber = mo.groups()
>>> print(areaCode)
415
>>> print(mainNumber)
555-4242
因为 mo.groups()
返回多个值的元组,所以你可以使用多重复制的技巧,每个值赋给一个独立的变量,就像前面的代码行: areaCode, mainNumber = mo.groups()
。
括号在正则表达式中有特殊的含义,如果你需要在文本中匹配括号,该怎么办呢?例如,你要匹配的电话号码可能将区号放在一对括号中。在这种情况下,就需要用倒斜杠对括号进行字符转义。在交互式环境中输入以下代码:
>>> phoneNumRegex = re.compile(r'(\(\d\d\d\)) (\d\d\d-\d\d\d\d)')
>>> mo = phoneNumRegex.search('My phone number is (415) 555-4242.')
>>> mo.group(1)
'(415)'
>>> mo.group(2)
'555-4242'
在传递给 re.compile()
的原始字符串中,(和)转义字符将匹配实际的括号字符。在正则表达式中,以下字符具有特殊含义:
. ^ $ * + ? { } [ ] \ | ( )
如果要检测包含这些字符的文本模式,那么就需要用倒斜杠对它们进行转义:
\. \^ \$ \* \+ \? \{ \} \[ \] \\ \| \( \)
要确保在正则表达式中,没有将转义的括号 (
和 )
误作为括号 (
和 )
。如果你收到类似“ missing)
”或“ unbalanced parenthesis
”的错误信息,则可能是忘记了为分组添加转义的右括号,例如以下示例:
>>> re.compile(r'(\(Parentheses\)')
Traceback (most recent call last):
--snip--
re.error: missing ), unterminated subpattern at position 0
这条错误信息告诉你,在 r'((Parentheses)'
字符串的索引0处有一个左括号,但缺少对应的右括号。