我想在输入代码时找到源代码中所有Python字符串的内容。我假设字符串包含在一行中,但它可能尚未关闭。
现在我有
for m in re.finditer('''(?P<open>(?:""")|"|(?:''\')|')(?:((?P<closed>.*?)(?P=open))|(?P<unclosed>.*))''', 'as"df'):
i = 3 if m.group(3) else 4
print m.group(i)
但是我希望有一个可预测的匹配组来搜索。像
这样的东西re.finditer('''(?P<open>(?:""")|"|(?:''\')|')(.*?)(?P=open)''', line)
更好,因为字符串文字的内容总是在匹配组中(但是这个字符串与尚未关闭的字符串不匹配)。
编辑:我对多行匹配很好,我的意思是通过将它们排除在输入之外来使问题更简单。
答案 0 :(得分:3)
你可以试试这个:
(?s)('''|"""|'|")((?:(?=([^"'\\]+|\\.|(?!\1)["']))\3)*)\1?
引用在第1组中捕获,最后使用反向引用来关闭字符串\1
。
[^"'\\]+ | \\. | (?!\1)["']
描述了允许的内容:
[^"'\\]+ # all that is not a quote or a backslash
\\. # an escaped character
(?!\1)["'] # a quote that is not the captured quote
然后,要重复这些元素而不冒catastrophic backtracking的风险,我会使用此技巧模拟atomic group:
(?>subpattern)*
=&gt; (?:(?=(subpattern))\1)*
注意:如果您要禁止多行匹配,则只需将允许的内容更改为
[^"'\r\n\\]+ | \\. | (?!\1)["']
并删除(?s)
修饰符。
[编辑]
如果要匹配字符串末尾的反斜杠(例如:text = r'''abc def ghi\
),则需要将模式更改为:
多线模式:
(?m)('''|"""|'|")((?:(?=([^"'\r\n\\]+|\\(?:.|$)|(?!\1)["']))\3)*)\1?
单线模式:
(?s)('''|"""|'|")((?:(?=([^"'\\]+|\\(?:.|$)|(?!\1)["']))\3)*)\1?
答案 1 :(得分:2)
这个怎么样:
^("""|'''|"|')((?!\\").*?)(?:(?<!\\)\1$|$)
当你遇到语法错误的字符串时,当你得到三个(在开始和结束时)有两个双引号时,我不确定你想要的行为。但据我所知,这应该可以胜任。
在代码中使用第二个匹配组。