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

Java正则表达式优化:解决SonarQube检测的栈溢出风险问题

问题描述

我编写了如下Java代码:

Pattern myPattern =
                Pattern.compile("Customer_[a-zA-Z]+([-_][a-zA-Z0-9]+)*(#[a-zA-Z0-9]+)*(_[a-zA-Z0-9]+)*\\.xlsx");

在构建项目时,SonarQube检测失败,提示:

重构此重复结构,其可能在处理大输入时导致栈溢出。

并标记了正则表达式中的以下部分:

(#[a-zA-Z0-9]+)*

以及:

(_[a-zA-Z0-9]+)*
修复方案

SonarQube标记的这两个结构属于嵌套贪婪重复,正则引擎处理这类结构时,若遇到超长且不匹配的输入,会触发大量递归回溯,最终导致栈溢出。核心问题是(X+)*这种嵌套结构,引擎会尝试拆分X+的匹配长度来满足外层*的要求,回溯深度随输入长度线性增长。

方式一:使用占有量词

Pattern myPattern = Pattern.compile("Customer_[a-zA-Z]+(?:[-_][a-zA-Z0-9]+)*(?:#[a-zA-Z0-9]++)*(?:_[a-zA-Z0-9]++)*\\.xlsx");

方式二:使用原子组

Pattern myPattern = Pattern.compile("Customer_[a-zA-Z]+(?:[-_][a-zA-Z0-9]+)*(?>#[a-zA-Z0-9]+)*(?>_[a-zA-Z0-9]+)*\\.xlsx");

改动说明

  • 将原捕获组(...)改为非捕获组(?:...),减少不必要的资源消耗
  • 对标记的重复结构,使用占有量词++或原子组(?>...):
    • 占有量词++会一次性占有所有符合条件的字符,匹配完成后不释放,避免回溯
    • 原子组(?>...)内的匹配结果一旦确定就不会被回溯修改
  • 两种改动都保持了原正则的匹配逻辑,同时彻底消除了栈溢出的风险

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 11:16:00