Java正则Matcher匹配跳过问题:相邻重复字符替换不符合预期
问题分析与解决方案
你的思路方向是对的,但代码里有个关键错误导致输出不符合预期,咱们一步步拆解问题:
问题出在哪?
你在循环里引入的i变量以及m.group(i)的用法完全是多余且错误的:
group(0)代表整个匹配到的连续重复字符串(比如第一次匹配到的aaa),group(1)是正则里的捕获组,也就是单个重复的字符(比如a)。- 每次循环
i++后,第二次匹配bb时你取的是group(1),它的长度永远是1,判断为奇数后就会保留b,导致bb没被删掉;后续匹配ccc时,i已经变成2,而你的正则只有1个捕获组,group(2)根本不存在,这会让逻辑完全偏离预期。
简单说,你需要判断的是整个连续重复串的长度,而非某个捕获组的长度,那个i变量完全没必要存在。
修正后的代码
删掉多余的i变量,改用m.group().length()获取整个匹配串的长度:
public static void main(String[] args) { String s = "aaabbcccddds"; StringBuffer output = new StringBuffer(); Pattern repeatedChars = Pattern.compile("([a-z])\\1+"); Matcher m = repeatedChars.matcher(s); while(m.find()) { if(m.group().length() % 2 == 0) { m.appendReplacement(output, ""); } else { m.appendReplacement(output, "$1"); } } m.appendTail(output); System.out.println(output); }
验证结果
输入aaabbcccddds时,逻辑会这样处理:
aaa长度3(奇数)→ 替换为单个abb长度2(偶数)→ 替换为空字符串ccc长度3(奇数)→ 替换为单个cddd长度3(奇数)→ 替换为单个d- 末尾的
s不匹配正则,直接保留
最终输出就是你预期的acds。
内容的提问来源于stack exchange,提问作者somnathchakrabarti
相关产品推荐
相关产品推荐

