使用replaceAll()时抛出PatternSyntaxException: Illegal repetition异常求助
解决正则替换时的
PatternSyntaxException: Illegal repetition异常 我明白你现在遇到的问题——你想从<pre><code>标签里提取{{ some | value }}格式的内容,然后替换其中的部分,但在调用replaceAll()的时候触发了正则语法异常。咱们先拆解问题根源,再一步步解决。
首先,你用\\{\\{(.*?)\\}\\}来匹配{{ }}包裹的内容是没问题的,能正确捕获到目标片段。但问题出在这段代码里:
text = text.replaceAll(match , value1);
这里的match是你从{{ }}里提取出的内容(比如some | value),而replaceAll()的第一个参数是正则表达式,其中的|是正则的特殊元字符(表示分支匹配),直接传入会被解析成正则语法,从而触发Illegal repetition异常。
解决方案一:用Pattern.quote()转义特殊字符
最简单的修复方式是把match转义成字面量字符串,让replaceAll()把它当作普通文本处理,而非正则表达式:
Pattern pattern = Pattern.compile("\\{\\{(.*?)\\}\\}"); Matcher matcher = pattern.matcher(text); List<String> matches = new ArrayList<>(); while(matcher.find()){ matches.add(matcher.group()); } for (String match : matches) { match = match.substring(2 , match.length()-2); String splitArray[] = match.split("\\|"); String value1 = splitArray[0].trim(); String value2 = splitArray[1].trim(); // 用Pattern.quote()包裹match,转义所有正则特殊字符 text = text.replaceAll(Pattern.quote(match), value1); }
解决方案二:用Matcher.appendReplacement()更高效处理
其实你完全可以跳过“收集匹配结果再循环替换”的步骤,直接用Matcher的appendReplacement()和appendTail()方法,一次遍历完成替换,还能彻底避免转义麻烦:
Pattern pattern = Pattern.compile("\\{\\{(.*?)\\}\\}"); Matcher matcher = pattern.matcher(text); StringBuffer result = new StringBuffer(); while (matcher.find()) { // 直接获取{{}}内部的内容,无需手动截取 String content = matcher.group(1); String[] splitArray = content.split("\\|"); String value1 = splitArray[0].trim(); // 把匹配到的整个{{...}}片段替换成目标值 matcher.appendReplacement(result, value1); } // 追加剩余未匹配的内容到结果中 matcher.appendTail(result); text = result.toString();
这种方式效率更高,因为只需要遍历一次字符串,而且不需要处理正则特殊字符的转义问题,appendReplacement()会自动基于匹配结果完成替换。
补充提示
如果你的{{ }}内容里可能出现其他正则特殊字符(比如*、+、?等),第一种方案的Pattern.quote()能统一处理这些情况;而第二种方案从根源上规避了问题,因为它直接基于正则匹配的分组进行替换,不需要再用字符串作为匹配条件。
内容的提问来源于stack exchange,提问作者siva
相关产品推荐
相关产品推荐

