7.5. 详细正则表达式

到目前为止,您一直在处理我称之为“紧凑”的正则表达式。正如您所见,它们难以阅读,即使您弄清楚了一个表达式的作用,也不能保证您在六个月后还能理解它。您真正需要的是内联文档。

Python 允许您使用称为 详细正则表达式 的东西来做到这一点。详细正则表达式与紧凑正则表达式在两个方面有所不同

通过一个例子,这将更加清晰。让我们重新审视您一直在使用的紧凑正则表达式,并将其转换为详细正则表达式。此示例展示了如何操作。

示例 7.9. 带有内联注释的正则表达式

>>> pattern = """
    ^                   # beginning of string
    M{0,4}              # thousands - 0 to 4 M's
    (CM|CD|D?C{0,3})    # hundreds - 900 (CM), 400 (CD), 0-300 (0 to 3 C's),
                        #            or 500-800 (D, followed by 0 to 3 C's)
    (XC|XL|L?X{0,3})    # tens - 90 (XC), 40 (XL), 0-30 (0 to 3 X's),
                        #        or 50-80 (L, followed by 0 to 3 X's)
    (IX|IV|V?I{0,3})    # ones - 9 (IX), 4 (IV), 0-3 (0 to 3 I's),
                        #        or 5-8 (V, followed by 0 to 3 I's)
    $                   # end of string
    """
>>> re.search(pattern, 'M', re.VERBOSE)                1
<_sre.SRE_Match object at 0x008EEB48>
>>> re.search(pattern, 'MCMLXXXIX', re.VERBOSE)        2
<_sre.SRE_Match object at 0x008EEB48>
>>> re.search(pattern, 'MMMMDCCCLXXXVIII', re.VERBOSE) 3
<_sre.SRE_Match object at 0x008EEB48>
>>> re.search(pattern, 'M')                            4
1 使用详细正则表达式时,最重要的是要记住,在使用它们时需要传递一个额外的参数:re.VERBOSE 是在 re 模块中定义的常量,它表示该模式应被视为详细正则表达式。如您所见,此模式有很多空格(所有空格都被忽略)和一些注释(所有注释都被忽略)。一旦您忽略了空格和注释,这与您在 上一节 中看到的正则表达式完全相同,但可读性要高得多。
2 这匹配字符串的开头,然后是四个可能的 M 中的一个,然后是 CM,然后是 L 和三个可能的 X 中的三个,然后是 IX,然后是字符串的结尾。
3 这匹配字符串的开头,然后是四个可能的 M 中的四个,然后是 D 和三个可能的 C 中的三个,然后是 L 和三个可能的 X 中的三个,然后是 V 和三个可能的 I 中的三个,然后是字符串的结尾。
4 这不匹配。为什么?因为它没有 re.VERBOSE 标志,所以 re.search 函数将该模式视为紧凑正则表达式,其中包含有效的空格和文字井号。Python 无法自动检测正则表达式是详细的还是紧凑的。Python 假设每个正则表达式都是紧凑的,除非您明确声明它是详细的。