如何重构被 SonarLint 标记为“可能导致堆栈溢出”的正则表达式

问题描述 投票:0回答:1

我的 CSV 文件中有一些类似于下面的行:

"A","B","C"

我可以确定所有值都将始终用双引号引起来,并用逗号分隔。

为了解析这些值,我使用这个正则表达式:

var regex  = ",(?=([^\"]*\"[^\"]*\")*[^\"]*$)";
var chunks = Stream.of(s.split(regex))
               .map(e -> e.substring(1, e.length() - 1))
               .toList();

这会产生一个

chunks
列表,其中包含值
A
B
C
。到目前为止,一切都很好。 然而,SonarLint 正在抱怨正则表达式。它说:

Refactor this repetition that can lead to a stack overflow for large inputs

正则表达式需要是什么样子才能避免发生堆栈溢出?

java regex sonarlint
1个回答
0
投票

这是因为你的正则表达式有重复。考虑重新考虑优化。
我相信,在您的情况下,

",(?=([^\"]*\"[^\"]*\")*[^\"]*$)"
给出的结果与您可以考虑的
",(?=([^\"]*\")*[^\"]*$)"
相同。
您可以参考here的完整声纳规则,其中指出:

为什么这是一个问题? Java正则表达式引擎使用递归方法 调用来实现回溯。因此,当 a 内重复时 正则表达式包含多个路径(即正文 重复包含交替 (|)、可选元素或其他元素 重复),尝试匹配正则表达式可能会导致堆栈 大输入时溢出。使用所有格时不会发生这种情况 量词(例如 + 而不是 )或使用字符类时 在重复中(例如 [ab] 而不是 (a|b))。

© www.soinside.com 2019 - 2024. All rights reserved.