5.4 注释模式

有时候,遇到的正则表达式很复杂,不但难以编写和阅读,也难以维护。如果正则表达式也像程序源代码一样,可以添加注释,阅读和维护就容易多了。

为解决这个问题,许多语言支持使用(?#comment)的记法添加注释,comment就是注释的内容。所以上一节的表达式(?m)\d.*可以写成这样:

(?m)(?#开启多行模式)\d(?#寻找数字字符开头的行).*

.NET、Python、Ruby、PHP都支持这种记法,Java和JavaScript则不支持。不过,还有一种注释的写法是很多语言都支持的,就是使用注释模式,此时,正则表达式对应的字符串可以跨越很多行。

例5-5 注释模式

multiline_str = "1 line\nno digit\n3 line"
lineBeginWithDigitRegex = r"""
(?mx)  # enable multiline and extended mode
^  # start of the line
\d  # digit
.*  # rest of the line
$  # end of the line
"""
print(re.findall(lineBeginWithDigitRegex, multiline_str))
# ['1 line', '3 line']

在注释模式下,正则表达式内部的空白字符都被忽略(一般来说,主要是ASCII编码中的空白字符,Unicode编码中的空白字符情况不定),注释则以#comment的形式加在正则表达式内部,每条注释从#开始,到行末结束。在许多文档中,都是以这种模式来解释复杂的表达式,并且会使用缩进表示层级结构,这样方便阅读和维护。

例5-6 在注释模式下展开正则表达式

dateRegex = re.compile(r"""
(?x)
    (
        \d{4}  # 年
        -
        \d{2}  # 月
        -
        \d{2}  # 日
    )
""")
print(dateRegex.findall('2018-11-11'))  # ['2018-11-11']

注释模式对应的模式修饰符为x(extended mode),也叫做宽松格式模式(free-spacing mode)。

表5-5 个语言中注释模式的预定义常量

语言 常量
.NET RegexOptions.IgnorePatternWhitespace
JAVA Pattern.COMMENTS
JavaScript /regex/x
PHP /regex/x
Python re.X
re.VERBOSE
Ruby /regex/x
Regex::EXTENDED

你可能注意到了,例5-5同时指定来两种模式:多行模式和注释模式,合写作(?mx)。如果需要同时使用多种模式,只要在(?modifier)中将模式修饰符排列起来就可以了。

如果希望同时使用多行模式和注释模式,使用预定义常量可以通过为运算符|。写法是re.M | re.X,效果和(?mx)是一样的。

multiline_str = "1 line\nno digit\n3 line"
reg_2 = re.compile(r'^\d.*$', re.M | re.X)
print(reg_2.findall(multiline_str))  # ['1 line', '3 line']

如果是PHP、Ruby和JavaScript,则在分隔符有直接并列模式对应的修饰符/regex/mx

你可能感兴趣的:(5.4 注释模式)