python - 为什么 python 在 re 中卡住(挂起)?

标签 python regex

我是 pythonizer perl 到 python 转换器的作者。我正在尝试引导它的最新版本,它卡在 re 模块中。我用 -mtrace -t 运行它,它在这里卡住了:

Perlscan.py(449):     if py == "'.pl'":
Perlscan.py(454):     term = "'"
Perlscan.py(456):     print('py: ', len(py), py)
py:  140 '\U0001f60e\U0001f941\U0001f3b9\U0001f3a4\U0001f3b8\U0001f49c\U0001f55b\U0001f385\U0001f3fb\u274c\u2b55\ufe0f\U0001f4af\U0001f1fa\U0001f1f8'
Perlscan.py(457):     if _m := re.search(
Perlscan.py(458):         r"""^(f?(?:'''|""\"|'|")(?:[A-Za-z]:)?)((?:(?:[\\/])?(?:[{][^}]+[}])*|[A-Za-z0-9_.-]*)*)[.]pl\b(.*)$""", py
Perlscan.py(457):     if _m := re.search(
 --- modulename: re, funcname: search
re.py(200):     return _compile(pattern, flags).search(string)
 --- modulename: re, funcname: _compile
re.py(290):     if isinstance(flags, RegexFlag):
re.py(292):     try:
re.py(293):         return _cache[type(pattern), pattern, flags]
Terminated

“终止”消息是我使用 kill 命令终止卡住的进程。当然,我似乎无法在小程序中重现这个问题。以下是导致程序卡住的源代码片段:

print('py: ', len(py), py)
if _m := re.search(
    r"""^(f?(?:'''|""\"|'|")(?:[A-Za-z]:)?)((?:(?:[\\/])?(?:[{][^}]+[}])*|[A-Za-z0-9_.-]*)*)[.]pl\b(.*)$""", py
):

我使用的是 python 3.10。

最佳答案

catastrophic backtracking在这里can be observed简单的字符串,如 f'''c:\folder-name\file name here.pl

具有无限量化分组的模式,其中 tend to cause 内包含可选的无限量化模式这种类型的正则表达式问题。

这里,(?:(?:[\\/])?(?:[{][^}]+[}])*|[A-Za-z0-9_.-]* )* 是错误模式,可以概括为 (?:a?b*|c*)*。在这里,两种替代方案都可以匹配无限量化的模式,当放置在正则表达式中间时,会导致正则表达式引擎尝试多种方法来匹配需要永远计算的输入字符串。

解决这种情况的方法是通过删除 * 量词来确保使用的模式与至少一个强制模式相匹配,例如(?:{[^}]+}|[A-Za-z0-9_\\/.-])*

请参阅regex demo .

关于python - 为什么 python 在 re 中卡住(挂起)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74010337/

相关文章:

python - 仅当前一个可选字符匹配时,如何使用正则表达式来匹配可选字符?

java - 将 String.split 与正则表达式一起使用

Ruby 扫描正则表达式

python - 你能将 opencv SIFT 与 tensorflow 模型集成吗?

python - grid.py 无法获取数据集的比率

python - 创建新 DataFrame 的性能

python - 在 setup.cfg 中设置 basedirlist 并在 make 中设置 PREFIX 指向 virtualenv

java - 使用匹配器和模式从字符串中提取 float

正则表达式转义 Groovy 中的特殊字符

python - 如何将符号放入列表