(我相信问题在(?s)。*?只是顺便说一句)
我需要从文件中提取一些函数。
我有这段代码:
pattern = "^\s*[a-zA-Z_]?.*void\s+[a-zA-Z_][a-zA-Z_0-9]*\s*\((?s).*?\).*?$"
objekt = re.findall(re.compile(pattern,re.MULTILINE), string)
其中string是
extern inline void
lineBreak ( void )
;
extern inline void debugPrintf
(
const int level,
const char * const format,
...)
{
return NULL;
}
extern void
debugPutc
(
const int level
,
const int c)
;
然而返回
extern inline void
lineBreak ( void )
;
extern inline void debugPrintf
(
const int level,
const char * const format,
...)
{
return NULL;
}
extern void
debugPutc
(
const int level
,
const int c)
当我在regex101上调试时,它返回我需要提取的3个函数。
有谁知道问题出在哪里?谢谢。
编辑:
就在此之前,我有这种模式:
"^\s*[a-zA-Z_]?.*void\s+[a-zA-Z_][a-zA-Z_0-9]*\s*\((?:\s*?.*?\s*?)*\)\s*?$"
并且一切都运行正常,除了有灾难性的回溯并且没有为其他类型工作然后无效(如双)
答案 0 :(得分:3)
它在documentation中说
请注意,
(?x)
标志会更改表达式的解析方式。它应该首先在表达式字符串中使用,或者在一个或多个空格字符之后使用。如果标志前面有非空白字符,则结果未定义。
其他旗帜似乎发生了其他奇怪的事情。在模式开始时.
受到最后(?s)
,第二次及以后的匹配的影响。
一旦设置,Python就无法关闭标志。而且没有办法限制旗帜。 (在Perl和其他一些版本中,您可以使用作用域(?s:.*?)
并禁用(?-s)
)
编写模式的另一种方法,就是你要寻求的效果:
pattern = r"^.*?\bvoid\s+[a-zA-Z_][a-zA-Z_0-9]*\s*\([\S\s]*?\).*$"
\b
匹配字边界。在单词字符(A-Z,a-z,0-9和“_”)和非单词字符之间。[\S\s]
将匹配任何非空格或空白字符。也就是说,任何角色,包括换行符。答案 1 :(得分:1)
你是对的,(?s)
让你搞砸了。在支持内联修饰符的大多数版本中,您可以在正则表达式中的任何位置插入(?s)
,并且单行模式将从该点开始并保持有效直到正则表达式结束,除非您使用{{1将其关闭}}。如果它在组内,模式将在组结束时重置。或者,您可以使用模式修改组(具有嵌入模式修饰符的非捕获组):(?-s)
。
但Python并不是那么灵活。它不支持模式修改的组,并且内联修饰符始终会影响整个正则表达式,无论您将它放在何处。作为Markus said,解决方案是使用(?s:...)
代替(JavaScript正则表达中经常使用的惯用法,它根本没有单行/ DOTALL模式)。
我还建议您对正则表达式使用Python的原始字符串表示法:
[\S\s]*?