我试图从多线生成线变量中提取多线值。以下测试用例无法在输入字符串中找到匹配项,我不得不承认我没有看到原因。有关在stdout上打印此示例代码“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()
答案 0 :(得分:2)
re.M意味着re.MULTILINE,但它不涉及dot的象征意义,它涉及^和$
的象征意义您需要指定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 '
答案 1 :(得分:1)
您的问题是默认情况下.
与换行符不匹配。如果启用Dotall修改器,它将起作用。
regex = re.compile(r'^FOO=(.+)(?<!\\)$', re.M | re.S)
您可以使用re.S
您的输出将是
a \
b
您的模式与包含换行符的模式匹配。
我不确定您想要使用多行修饰符re.M
实现什么。它使^
和$
匹配行开始/结束。我假设你可以删除它。
我也不确定你想要用负面的后视(?<!\\)
实现什么,我认为你应该澄清你的预期输出。 (是否要删除\ b中的换行符?)
答案 2 :(得分:0)
我想出了这个:
^FOO=((([^\\]*\\\n)*)[^\n]+)
它假设反斜杠后面没有空格。
答案 3 :(得分:0)
您的示例文本中包含大量空格字符,包括反斜杠后。我认为这不是你想要的,因为反斜杠的意思是逃避通常标记条目结束的换行符。
但反斜杠也可用于转义其他字符,包括反斜杠。如果值恰好以反斜杠结束,则它将在makefile中显示为两个反斜杠。正则表达式中的lookbehind将“看到”第二个,并错误地将其视为行继续的一部分。
如果你想添加另一个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解释的那样,^
匹配行的开头,$
匹配行的结尾。