Java正则表达式替换指定文本未生效,请求排查解决
搞定Java正则替换没生效的问题
嘿,我太懂你这种抓耳挠腮的感觉了——明明单独处理匹配到的分组能得到正确结果,但整个StringBuilder就是没更新,简直让人摸不着头脑!
问题出在哪?
大概率是你踩了新手常犯的坑:你修改的只是匹配分组的副本,根本没把替换后的内容写回原StringBuilder里。Matcher的group()方法返回的是原字符串的子串拷贝,你改这个拷贝,原StringBuilder完全没感知到啊!
举个典型的错误代码例子,是不是和你写的差不多?
StringBuilder sb = new StringBuilder(readFileContent("input.txt")); Pattern pattern = Pattern.compile("href=\"javascript:openWin(')(Images/.*?)(',\\d+,\\d+)\""); Matcher matcher = pattern.matcher(sb); if (matcher.find()) { // 这里只是把分组内容替换了,但没放回原sb String fixedPart = matcher.group(2).replace("Images", "http://google.com/Images"); } // 输出自然还是原内容 System.out.println(sb);
正确的打开方式
要给StringBuilder做正则替换,得用Matcher的appendReplacement()和appendTail()组合拳,它们会帮你一步步构建替换后的完整内容:
import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.regex.Matcher; import java.util.regex.Pattern; public class ImageUrlFixer { public static void main(String[] args) throws IOException { // 先把文件内容读成字符串(也可以用StringBuilder,String操作更直观) String content = new String(Files.readAllBytes(Paths.get("input.txt"))); // 写正则的时候,把要替换的"Images"前后的内容都分组抓牢 Pattern pattern = Pattern.compile("(href=\"javascript:openWin('))(Images)(/.*?',\\d+,\\d+\")"); Matcher matcher = pattern.matcher(content); StringBuilder resultSb = new StringBuilder(); // 循环处理每一个匹配项 while (matcher.find()) { // 把前半段、替换后的前缀、后半段拼起来,塞进结果里 matcher.appendReplacement(resultSb, matcher.group(1) + "http://google.com/Images" + matcher.group(4)); } // 别忘了把最后一段没匹配到的内容也加上 matcher.appendTail(resultSb); // 现在输出就是替换好的内容啦 System.out.println(resultSb); // 要是要写回文件的话,用Files.write就行 } }
如果你的文件内容不是特别大,其实用String的replaceAll()更简单,一行搞定:
String fixedContent = content.replaceAll("(href=\"javascript:openWin('))Images", "$1http://google.com/Images");
划重点
- 正则分组要准:确保你只替换
Images这部分,其他乱七八糟的转义字符和参数都原封不动保留。 - 别改group的副本:改了也白改,必须用Matcher的替换方法或者重新拼接字符串,把修改后的内容整合回去。
- 用appendReplacement要循环:如果字符串里有多个匹配项,得循环处理所有,最后一定要加appendTail。
这样操作之后,你想要的替换效果肯定就出来啦!
内容的提问来源于stack exchange,提问作者Rose
相关产品推荐
相关产品推荐

