You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何重构被SonarLint标记为易引发栈溢出的正则表达式?

问题描述

我有格式如下的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

请问需要将该正则表达式修改为怎样的形式,才能避免栈溢出问题?

优化方案

方法1:优化正则表达式,消除回溯风险

原正则的嵌套重复结构([^\"]*\"[^\"]*\")*会让Java正则引擎产生大量递归回溯,处理长文本时容易触发栈溢出。可以用原子组(?>...)阻止回溯,优化后的正则如下:

var regex = ",(?=((?>[^\"]*\"){2})*[^\"]*$)";

原子组会锁定组内匹配的结果,不允许引擎回溯调整,大幅减少递归调用次数,避免栈溢出,同时保持原有的匹配逻辑(只匹配不在双引号内的逗号)。

方法2:换用更简单的字符串处理逻辑(推荐)

既然已经明确所有值都被双引号包裹,完全可以不用复杂正则,直接通过字符串截取+分割实现:

var chunks = Stream.of(s.substring(1, s.length() - 1).split("\",\""))
               .toList();

先去掉字符串首尾的双引号,再按","分割,逻辑直观清晰,没有正则回溯的性能问题,不管输入多长都不会出现栈溢出,最终同样能得到A、B、C的结果。

内容的提问来源于stack exchange,提问作者Ch Ryder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 23:26:05