10

我有一个冗长的 python 正则表达式字符串(有很多空格和注释),我想将其转换为“正常”样式(用于导出到 javascript)。特别是,我需要这个非常可靠。如果有任何明显正确的方法可以做到这一点,这就是我想要的。例如,一个幼稚的实现会破坏一个像 regex 这样的正则表达式r' \# # A literal hash character',这是不行的。

做到这一点的最好方法是强制 python re 模块给我一个我的正则表达式的非详细表示,但我看不到这样做的方法。

4

1 回答 1

7

我相信您只需要解决这两个问题即可去除冗长的正则表达式:

  1. 删除行尾的评论
  2. 删除未转义的空格

试试这个,它用单独的正则表达式替换链接 2:

import re

def unverbosify_regex_simple(verbose):
    WS_RX = r'(?<!\\)((\\{2})*)\s+'
    CM_RX = r'(?<!\\)((\\{2})*)#.*$(?m)'

    return re.sub(WS_RX, "\\1", re.sub(CM_RX, "\\1", verbose))

上面是一个简化版本,保留转义空格原样。结果输出会有点难以阅读,但应该适用于正则表达式平台。

或者,对于“取消转义”空格(即'\'=>'')并返回我认为大多数人所期望的稍微复杂一点的答案:

import re

def unverbosify_regex(verbose):
    CM1_RX = r'(?<!\\)((\\{2})*)#.*$(?m)'
    CM2_RX = r'(\\)?((\\{2})*)(#)'
    WS_RX  = r'(\\)?((\\{2})*)(\s)\s*'

    def strip_escapes(match):
        ## if even slashes: delete space and retain slashes
        if match.group(1) is None:
            return match.group(2)

        ## if number of slashes is odd: delete slash and keep space (or 'comment')
        elif match.group(1) == '\\':
            return match.group(2) + match.group(4)

        ## error
        else:
            raise Exception

    not_verbose_regex = re.sub(WS_RX, strip_escapes,
                          re.sub(CM2_RX, strip_escapes,
                            re.sub(CM1_RX, "\\1", verbose)))

    return not_verbose_regex

更新:添加注释以解释偶数 v. 奇数斜线计数。修复了 CM_RX 中的第一组以在斜线计数为奇数时保留完整的“注释”。

更新 2:修正了评论正则表达式,它没有正确处理转义的哈希。应该同时处理 "\# #escaped hash" 以及 "# comment with \# escaped hash" 和 "\\# comment"

更新 3:添加了不清理转义空格的简化版本。

更新 4:进一步简化以消除可变长度的负后视(和反向/反向技巧)

于 2013-02-17T08:13:24.387 回答