用python regexp匹配多行make-line变量赋值



我试图从多行make-line变量分配中提取多行值。下面的测试用例无法在输入字符串中找到匹配项,我必须承认我不知道为什么。如果能帮助使这个示例代码在标准输出上打印"a b",那将是非常受欢迎的。

#!/usr/bin/env python                                                                                                 
def test():
    s = r"""                                                                                                          
FOO=a                                                                                                                
  b                                                                                                                   
"""
    import re
    print type(s),s
    regex = re.compile(r'^FOO=(.+)(?<!\)$', re.M)
    m = regex.search(s)
    print m.group(1)
if __name__ == '__main__':
    test()

re。M表示re.MULTILINE,但它与点的符号无关,它与^和$

的符号有关。

您需要指定re.DOTALL以使点能够与'n'匹配

def test():
    s = r"""    
FOO=a     
  b
  """
    import re
    print repr(s)
    print '---------------------'
    regex = re.compile(r'^FOO=(.+)(?<!\)$', re.M)
    print regex.search(s).group(1)
    print '---------------------'
    regex = re.compile(r'^FOO=(.+)(?<!\)$', re.M|re.DOTALL)
    print regex.search(s).group(1)
test()
结果

'    nnFOO=a \    nn  bnn  '
---------------------
a     
-----
'a \    '
---------------------
a     
  b

-----
'a \    nn  bnn  '

您的问题是.默认情况下不匹配换行符。如果你启用Dotall修饰符,它将工作。

regex = re.compile(r'^FOO=(.+)(?<!\)$', re.M | re.S)

使用re.S

你的输出将是

 b

你的模式只匹配包含换行符的模式。

我不确定你想用多行修饰符re.M实现什么。它使^$匹配成为行开始/结束。我想你可以把它去掉。

我也不确定你对(?<!\)的负面看法想达到什么目的,我认为你应该澄清你的预期产出。(是否要删除a b中的换行符?)

我想出了这个:

^FOO=((([^\]*\n)*)[^n]+)

假定反斜杠后面没有空格

示例文本中有很多空格字符,包括反斜杠后面的空格字符。我认为这不是您想要的,因为反斜杠的作用是转义通常标记条目结束的换行符。

但是反斜杠也可以用来转义其他字符,包括反斜杠。如果一个值恰好以反斜杠结尾,它将在makefile中显示为两个反斜杠。regex中的后看将"看到"第二个,并错误地将其视为行延续的一部分。

如果您正在考虑添加另一个向后查看来查看反斜杠是否被转义,现在让我阻止您。这个问题已经被讨论过很多次了,但回头看的方法是行不通的。您需要的是这样的内容:

regex = re.compile(r'^FOO=([^n\]*(?:\.[^n\]*)*)$', re.M | re.S)

第一个[^n\]*消耗尽可能多的非换行、非反斜杠字符,然后将控制权交给下一部分。如果没有到达字符串的末尾,它会尝试匹配一个反斜杠,后面跟着任何字符(包括换行,多亏了re.S修饰符),后面跟着一些更"正常"的字符。它在循环中继续这样做,直到(假设输入是有效的)遇到未转义的换行或输入结束。

虽然re.S修饰符允许点匹配换行符,但re.M修饰符也需要;这就是让^匹配行首和$匹配行尾的原因,正如@stema解释的那样。

最新更新