【问题标题】:Python multiline regex delimiterPython多行正则表达式分隔符
【发布时间】:2016-09-30 16:54:36
【问题描述】:

拥有这个多行变量:

raw = '''
CONTENT = ALL
TABLES = TEST.RAW_1
        , TEST.RAW_2
        , TEST.RAW_3
        , TEST.RAW_4
PARALLEL = 4
'''

结构始终为TAG = CONTENT,两个字符串都不是固定的,CONTENT 可以包含新行。

我需要一个 regex 来获取:

[('CONTENT', 'ALL'), ('TABLES', 'TEST.RAW_1\n        , TEST.RAW_2\n        , TEST.RAW_3\n        , TEST.RAW_4\n'), ('PARALLEL', '4')]

尝试了多种组合,但我无法在 TABLES 标签的正确位置停止 regex engine,因为它的内容是 由下一个标签分隔的多行字符串

来自解释器的一些尝试

>>> re.findall(r'(\w+?)\s=\s(.+?)', raw, re.DOTALL)
[('CONTENT', 'A'), ('TABLES', 'T'), ('PARALLEL', '4')]


>>> re.findall(r'^(\w+)\s=\s(.+)?', raw, re.M)
[('CONTENT', 'ALL'), ('TABLES', 'TEST.RAW_1'), ('PARALLEL', '4')]


>>> re.findall(r'(\w+)\s=\s(.+)?', raw, re.DOTALL)
[('CONTENT', 'ALL\nTABLES = TEST.RAW_1\n        , TEST.RAW_2\n        , TEST.RAW_3\n        , TEST.RAW_4\nPARALLEL = 4\n')]

谢谢!

【问题讨论】:

    标签: python regex multiline multilinestring


    【解决方案1】:

    您可以使用积极的前瞻来确保您正确地延迟匹配值:

    (\w+)\s=\s(.+?)(?=$|\n[A-Z])
                    ^^^^^^^^^^^^
    

    与 DOTALL 修饰符一起使用,以便 . 可以匹配换行符。 (?=$|\n[A-Z]) 前瞻将要求 .+? 匹配到字符串的末尾,或匹配到后跟大写字母的换行符。

    请参阅regex demo

    另一种更快的正则表达式(因为它是上述表达式的展开版本) - 但 DOTALL 修饰符不应该与它一起使用:

    (\w+)\s*=\s*(.*(?:\n(?![A-Z]).*)*)
    

    another regex demo

    解释

    • (\w+) - 第 1 组捕获 1+ 个单词字符
    • \s*=\s* - 一个 = 符号,包含可选 (0+) 个空格
    • (.*(?:\n(?![A-Z]).*)*) - 第 2 组捕获 0+ 序列:
      • .* - 除换行符以外的任何 0+ 个字符
      • (?:\n(?![A-Z]).*)* - 0+ 个序列:
        • \n(?![A-Z]) - 换行符后面不跟大写 ASCII 字母
        • .* - 除换行符以外的任何 0+ 个字符

    Python demo:

    import re
    p = re.compile(r'(\w+)\s=\s(.+?)(?=$|\n[A-Z])', re.DOTALL)
    raw = '''
    CONTENT = ALL
    TABLES = TEST.RAW_1
            , TEST.RAW_2
            , TEST.RAW_3
            , TEST.RAW_4
    PARALLEL = 4
    '''
    print(p.findall(raw))
    

    【讨论】:

    • 惊人的解释!巨大的regex kung-fu .. 非常感谢 Wiktor!
    猜你喜欢
    • 2020-08-04
    • 2013-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多