我希望匹配正则表达式\(.*\)
,\[.*\]
,\{.*\}
和\<.*\>
。有没有办法组合这些正则表达式?
例如,我想到的是:
([\(\[\{\<]).*\1
,但当然匹配\(.*\(
,\[.*\[
,\{.*\{
和\<.*\<
。
我的目标是能够匹配以前的正则表达式组,但在匹配之前将一个函数应用于该组。
考虑:
def match_pairs(pairs):
re = '|'.join("({begin}.*{end})".format(begin=beg, end=end) for (beg, end) in pairs)
return re
我正在考虑使用与上述函数类似的东西,但理想情况下这个函数不会返回一个非常长的正则表达式。如果您认为这个问题没有任何实际价值,请告诉我。我仍然很想知道Python3是否支持这样的任何功能,有点像re.sub
可以将一个函数作为替代。如果不存在此类功能,我如何编写match_pairs
以便它可以将["()", "[]", "[]", "{}"]
作为参数?
答案 0 :(得分:1)
此任务的明显(和最短)正则表达式为\(.*\)|\[.*\]|\{.*\}|\<.*\>
。
缺点是您有.*
子模式的四个副本,因此如果您需要更改它,则必须在4个位置更改它。幸运的是,我们可以通过使用捕获组来解决这个问题:
(?:\(()|\[()|\{()|<()).*(?:\1\)|\2\]|\3\}|\4>)
这可能看起来令人困惑,但实际上非常简单。模式构建如下:
(?:opening_char_1()|opening_char_2()|...).*(?:\1closing_char_1|\2closing_char_2|...)
这使用了一个相当简单的小技巧:每个开场角色((
,[
,{
,<
)都附带一个捕获组,如下所示:{{ 1}}。这允许我们“记住”哪个开头字符匹配 - 如果捕获组1匹配,我们知道开头字符是\[()
。如果捕获组2匹配,则开头字符为(
,依此类推。所以我们只需使用反向引用([
,\1
等)来找出开头字符是什么,然后匹配相应的结束字符。