我试图从多行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解释的那样。