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

字符串正则重复替换问题:浮点数转IntPMF格式的解决方案咨询

Fixing Repeated Replacement Issue in Java Float-to-IntPMF Conversion Function

Looks like you ran into a classic "replacement loop" issue here—your current code is re-scanning the entire string every time you do a replaceAll, which means the newly generated floats in your IntPMF output get picked up by the regex and replaced again, leading to that messy nested result.

Root Cause

The problem stems from using String.replaceAll() inside a while(m.find()) loop. Each call to replaceAll() runs your regex against the modified string (not the original input). So after you replace "0.5" with IntPMF[(0;0.5)(1;0.5)], the 0.5 values inside that new string are valid matches for your regex, and they get replaced again in the next loop iteration.

Solution: Use Matcher's Incremental Replacement Methods

The correct fix is to leverage Matcher.appendReplacement() and Matcher.appendTail(). These methods build the result incrementally, processing matches from the original string without re-scanning the replaced content. Here's your updated code:

public static String replaceDoubles(String stoEx) {
    Pattern p = Pattern.compile("(\\d+(?:\\.[0-9]\\d*))");
    Matcher m = p.matcher(stoEx);
    StringBuffer sb = new StringBuffer();
    while (m.find()) {
        double d = Double.parseDouble(m.group(1));
        int lower = (int) Math.floor(d);
        int upper = lower + 1;
        double decimalPart = round(d - lower, 2);
        double rest = round(1 - decimalPart, 2);
        String replacement = "IntPMF[(" + lower + ";" + rest + ")(" + upper + ";" + decimalPart + ")]";
        // Append content up to current match + replacement (no re-scanning)
        m.appendReplacement(sb, replacement);
    }
    // Add any remaining text after the last match
    m.appendTail(sb);
    return sb.toString();
}

// Helper method for rounding (ensure this is accessible)
private static double round(double value, int places) {
    if (places < 0) throw new IllegalArgumentException("Decimal places cannot be negative");
    long factor = (long) Math.pow(10, places);
    value = value * factor;
    long roundedValue = Math.round(value);
    return (double) roundedValue / factor;
}

Why This Works

  • appendReplacement() adds all text from the end of the last processed match up to the current match, plus your custom replacement, to the StringBuffer. It never re-processes content that's already been added to the buffer.
  • appendTail() handles any leftover text in the original string that wasn't matched by the regex.

I also simplified the lower value calculation using Math.floor(d) instead of splitting the string—this is more reliable for edge cases like "1.0" or "2.999" where string splitting might behave unexpectedly.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 13:32:52