我有正则表达式:
(.*\n)+DOCUMENTATION.*(\"\"\"|''')\n-*\n?((.*\n)+?)(\2)(?s:.*)
女巫我正在尝试处理这样的文件:
#!/usr/bin/python
# -*- coding: utf-8 -*-
# <GNU license here>
DOCUMENTATION = """
module: foo
short_description: baz
<some more here>
"""
<rest of the python code>
我需要从中获取DOCUMENTATION部分。
它工作得很好但不是python。问题在于内联修饰符?s:.*
,我用它来捕获文件的其余部分(任何字符包括新行零次或多次)。看起来它在python中有些不同。
这里以regex101为例。当我将它切换到python时显示错误。
注意:我无法全局设置修改器。 (我只能将正则表达式规则传递给某个python模块)。
答案 0 :(得分:12)
Python实现 inline (embedded) modifiers ,例如(?s)
,(?i)
或(?aiLmsux)
,但不是非捕获组修饰符的一部分你试图使用。
(?smi:subpattern)
适用于Perl和PCRE,但不适用于Python。
此外,在模式中的任何位置使用内联修饰符都适用于整个匹配,并且无法将其关闭。
<强> From regular-expressions.info 强>
在Python中,将修饰符放在正则表达式的中间会影响 整个正则表达式。所以在Python中,(?i)caseless
和caseless(?i)
都属于这种情况 不敏感的。
示例:强>
import re
text = "A\nB"
print("Text: '%s'\n---" % text)
patterns = [ "a", "a(?i)", "A.*B", "A(?s).*B", "A.*(?s)B"]
for p in patterns:
match = re.search( p, text)
print("Pattern: '%s' \tMatch: %s" % (p, match.span() if match else None))
<强>输出:强>
Text: 'A
B'
---
Pattern: 'a' Match: None
Pattern: 'a(?i)' Match: (0, 1)
Pattern: 'A.*B' Match: None
Pattern: 'A(?s).*B' Match: (0, 3)
Pattern: 'A.*(?s)B' Match: (0, 3)
(?s)
(又名单行或re.DOTALL
)使 .
也匹配换行符。而且由于您尝试将其设置为模式的一部分,因此有两种选择:
(?s)
(以标记或内联方式传递),并使用 [^\n]*
代替点,以匹配除换行之外的任何字符。[\S\s]*
代替点,以匹配包括换行符在内的任何字符。字符类包括所有空格和所有不是空格(因此,所有字符)。
对于您提供的特定情况,您可以使用以下表达式:
(?m)^DOCUMENTATION.*(\"{3}|'{3})\n-*\n?([\s\S]+?)^\1[\s\S]*
注意:这篇文章介绍re module中的内联修饰符,而Matthew Barnett's regex module实际上实现了内联修饰符(作用域标记),其行为与PCRE和Perl。