分组

    除了简单地判断是否匹配之外,正则表达式还有提取子串的强大功能。用 () 表示的就是要提取的分组(Group)。比如:

    ^(\d{3})-(\d{3,8})$ 分别定义了两个组,可以直接从匹配的字符串中提取出区号和本地号码:

    >>> m = re.match(r'^(\d{3})-(\d{3,8})$', '010-12345')

    >>> m

    <_sre.SRE_Match object; span=(0, 9), match='010-12345'>

    >>> m.group(0)

    '010-12345'

    >>> m.group(1)

    '010'

    >>> m.group(2)

    '12345'

    如果正则表达式中定义了组,就可以在 Match 对象上用 group() 方法提取出子串来。

    注意到 group(0) 永远是原始字符串, group(1) group(2) ……表示第1、2、……个子串。

    提取子串非常有用。来看一个更凶残的例子:

    >>> t = '19:05:30'

    >>> m = re.match(r'^(0[0-9]|1[0-9]|2[0-3]|[0-9])\:(0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]|[0-9])\:(0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]|[0-9])$', t)

    >>> m.groups()

    ('19', '05', '30')

    这个正则表达式可以直接识别合法的时间。但是有些时候,用正则表达式也无法做到完全验证,比如识别日期:

    '^(0[1-9]|1[0-2]|[0-9])-(0[1-9]|1[0-9]|2[0-9]|3[0-1]|[0-9])$'

    对于 '2-30' '4-31' 这样的非法日期,用正则还是识别不了,或者说写出来非常困难,这时就需要程序配合识别了。