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

SonarLint提示正则重复易致栈溢出,求匹配至少6个数字的优化正则

解决方案

正则表达式优化方案

原正则的问题在于嵌套的贪婪重复结构会引发大量回溯,SonarLint的警告正是针对这种潜在的栈溢出风险。优化后的正则可以避免过度回溯,同时满足需求:

String patternString = "^(?=(?:.*?\\d){6}).*$";

正则说明

  • ^(?=(?:.*?\\d){6}):正向预查,确保字符串中至少包含6个数字。.*?是非贪婪匹配任意字符,会尽快定位到下一个数字,大幅减少回溯次数;(?:...)是非捕获组,避免不必要的内存开销。
  • .*$:匹配整个字符串,符合matches()方法要求全串匹配的规则。

更高效的非正则替代方案

如果追求极致性能(尤其是处理大文本时),直接遍历字符串统计数字数量是更优的选择,完全规避正则引擎的回溯问题:

public static boolean hasAtLeastSixDigits(String s) {
    int digitCount = 0;
    for (char c : s.toCharArray()) {
        if (Character.isDigit(c)) {
            digitCount++;
            if (digitCount >= 6) {
                return true;
            }
        }
    }
    return false;
}

修改后的测试代码

使用优化后的正则:

import java.util.regex.Pattern; 
import java.util.regex.Matcher;

public class MyClass {
    public static void main(String[] args) {     
        String[] strings = { "JamesBond1.zip", "JamesBond 1 2 3456.zip", "JaneBond X 3-4-2024"};        
        String patternString = "^(?=(?:.*?\\d){6}).*$";     
        Pattern pattern = Pattern.compile(patternString);      
        for (String s : strings) {         
            Matcher matcher = pattern.matcher(s);         
            if (matcher.matches()) {              
                System.out.println("\"" + s + "\" matches the pattern.");         
            } else {              
                System.out.println("\"" + s + "\" does not match the pattern.");         
            }     
        } 
    }
}

使用非正则方法:

public class MyClass {
    public static void main(String[] args) {     
        String[] strings = { "JamesBond1.zip", "JamesBond 1 2 3456.zip", "JaneBond X 3-4-2024"};        
        for (String s : strings) {         
            if (hasAtLeastSixDigits(s)) {              
                System.out.println("\"" + s + "\" matches the pattern.");         
            } else {              
                System.out.println("\"" + s + "\" does not match the pattern.");         
            }     
        } 
    }

    public static boolean hasAtLeastSixDigits(String s) {
        int digitCount = 0;
        for (char c : s.toCharArray()) {
            if (Character.isDigit(c)) {
                digitCount++;
                if (digitCount >= 6) {
                    return true;
                }
            }
        }
        return false;
    }
}

两种方案都能满足预期:第一个字符串不匹配,后两个匹配,同时消除SonarLint的警告。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 21:05:20