【问题标题】:matching a multiline make-line variable assignment with a python regexp将多行生成行变量赋值与 python 正则表达式匹配
【发布时间】:2011-07-08 12:03:15
【问题描述】:

我正在尝试从多行生成行变量分配中提取多行值。以下测试用例无法在输入字符串中找到匹配项,我不得不承认我看不到原因。非常欢迎帮助使此示例代码在标准输出上打印“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()

【问题讨论】:

  • 不要忘记对您认为有用的答案进行投票,如果其中任何一个解决了您的问题,请将其标记为“已接受”! SO 的整个想法是查看答案/问题,以标记哪个对遇到相同问题的程序员有用! :)

标签: python regex multiline


【解决方案1】:

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()

结果

'    \n\nFOO=a \\    \n\n  b\n\n  '
---------------------
a \    
-----
'a \\    '
---------------------
a \    

  b


-----
'a \\    \n\n  b\n\n  '

【讨论】:

  • 哈哈。那是缺失的部分。不过,我注意到的一件事是,这个正则表达式匹配从匹配开始到字符串内容结束的所有内容。理想情况下,我想让它只匹配到下一个\n,其前一个字符不是'\'。我(成功地)尝试了以下正则表达式:“^FOO=(.+?)(?
【解决方案2】:

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

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

您使用re.S 这样做

你的输出将是

一个\

 b

您的模式确实与包括换行符在内的模式匹配。

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

我也不确定你想用你的负面观察(?&lt;!\\) 来实现什么,我认为你应该澄清你的预期输出。 (是否要删除 a\b 中的换行符?)

【讨论】:

    【解决方案3】:

    我想出了这个:

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

    它假定反斜杠后面没有空格。

    【讨论】:

      【解决方案4】:

      您的示例文本中包含大量空格字符,包括反斜杠之后。我认为这不是您想要的,因为反斜杠的目的是转义通常会标记条目结束的换行符。

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

      如果您正在考虑添加另一个lookbehind 以查看反斜杠是否被转义,让我现在阻止您。这已被多次讨论,并且无法使后向方法起作用。你想要的是这样的:

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

      See it in action on ideone

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

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

      【讨论】:

        猜你喜欢
        • 2021-12-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-02-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多