有时候,遇到的正则表达式很复杂,不但难以编写和阅读,也难以维护。如果正则表达式也像程序源代码一样,可以添加注释,阅读和维护就容易多了。
为解决这个问题,许多语言支持使用(?#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<br />re.VERBOSE |
Ruby | /regex/x<br />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
。
网友评论