【发布时间】:2019-02-23 15:46:18
【问题描述】:
我在使用 re.search() 或 re.findall() 时遇到问题。但让我先解释一下。我正在搜索 C 代码,其中包含如下定义:
#define SOME_FUNCTION( someArgument, someMoreArgument)
有时,当它们有很多参数时,它们会被包装起来,所以它们看起来像这样:
#define ANOTHER_FUNCTION( moreArgument, evenMoreArguments,
anAwfulLotOfArguments, youGetIt)
现在我正在使用 python 扫描这些文件以找到其中的每一个定义。我的正则表达式如下所示:
#define [A-Z,_]*\((?:.|\s)+?\"
在像regex101.com 这样的测试引擎中使用单行和多行定义进行测试时,它可以完美运行。
但是,当我将它与 python (3.4.1) 一起使用时,它仅适用于单行定义。当它尝试扫描多行定义时,它只是停止执行(尽管我可以用 Ctrl + C 中断它)。我尝试使用:
regexFullMacro = re.compile("#define [A-Z,_]*\((?:.|\s)+?\)")
match = regexFullMacro.search(searchString)
还有
regexFullMacro = re.compile("#define [A-Z,_]*\((?:.|\s)+?\)")
match = regexFullMacro.findall(searchString)
当涉及多行时,两者都尝试停止响应。
以前有没有人遇到过这个问题,或者我只是完全愚蠢并且遗漏了一些明显的东西?
【问题讨论】:
-
当您在 regex101 上进行测试时,您是否使用源文件的全部内容作为样本?您可能在回溯方面遇到问题,但如果您仅使用短字符串进行测试,这将不会引起注意...
-
一个明显的事情是永远不要在正则表达式模式中使用
(?:.|\s)+?。它会导致如此重的回溯,以至于引擎卡住了。您总是希望.带有 DOTALL 修饰符或[\s\S]在需要仅将此行为应用于模式的一部分时。在这种情况下,"#define [A-Z,_]*\([^()]+\)"应该足够了,因为否定字符类[^()]匹配除(和)之外的任何字符,包括换行符。 -
@WiktorStribiżew 对。在那个地方改用
[^)]+,这不会做任何回溯。 -
感谢您的快速回复。我使用了@WiktorStribiżew 提供的解决方案,它完美无缺。如果我可以请您帮忙,您能否描述一下,[^()]+ 比 (?:.|\s)+ 做得更好的地方是什么?为什么该解决方案不会产生任何回溯?那太棒了