正则表达式无法匹配字符串末尾的压缩词问题求助
问题原因
你的代码在修改StringBuilder的同时复用同一个Matcher,导致Matcher的位置追踪逻辑混乱。每次插入或删除字符都会改变字符串的长度和字符位置,而Matcher的find()方法是从上次匹配的结束位置继续扫描。当字符串被修改后,后续的位置偏移计算错误,最终导致最后一个匹配项u4被跳过。
修复方案
方案一:每次处理后重新创建Matcher
每次处理完一个压缩项后,重新生成Matcher并从头扫描,直到没有匹配项为止。这种方式简单直观,适合短字符串场景:
StringBuilder text = new StringBuilder("Hel2o peo7ple it is ou6r wo3rld gu4ys"); Pattern pattern = Pattern.compile("[a-z]\\d"); boolean hasMatch; do { hasMatch = false; Matcher matcher = pattern.matcher(text); if (matcher.find()) { hasMatch = true; int start = matcher.start(); int repeatCount = Integer.parseInt(text.substring(start + 1, start + 2)); char targetChar = text.charAt(start); // 删除数字 text.deleteCharAt(start + 1); // 插入重复字符 for (int i = 0; i < repeatCount - 1; i++) { text.insert(start + 1, targetChar); } } } while (hasMatch); System.out.println(text);
方案二:逆序处理匹配项
先一次性扫描所有匹配项的起始位置,然后从后往前处理。这样修改前面的字符不会影响已经记录的后面的匹配位置,效率更高,适合长字符串:
import java.util.ArrayList; import java.util.Collections; import java.util.List; public class UncompressText { public static void main(String[] args) { StringBuilder text = new StringBuilder("Hel2o peo7ple it is ou6r wo3rld gu4ys"); Pattern pattern = Pattern.compile("[a-z]\\d"); Matcher matcher = pattern.matcher(text); // 收集所有匹配项的起始索引 List<Integer> matchPositions = new ArrayList<>(); while (matcher.find()) { matchPositions.add(matcher.start()); } // 逆序处理,避免修改影响后续位置 Collections.reverse(matchPositions); for (int start : matchPositions) { int repeatCount = Integer.parseInt(text.substring(start + 1, start + 2)); char targetChar = text.charAt(start); text.deleteCharAt(start + 1); for (int i = 0; i < repeatCount - 1; i++) { text.insert(start + 1, targetChar); } } System.out.println(text); } }
两种方案都能得到预期输出:Hello peooooooople it is ouuuuuur wooorld guuuuys
内容的提问来源于stack exchange,提问作者Timur
相关产品推荐
相关产品推荐

