字符串正则重复替换问题:浮点数转IntPMF格式的解决方案咨询
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 theStringBuffer. 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

