String input = "<li><a href=\"../../jbatch/hello/\" >anchor</a></li>"; String expected = "<li><a href=\"/entry/articles-jbatch-hello\" >anchor</a></li>";
Complex string replacing on Java
TweetPosted on Tuesday Feb 10, 2015 at 10:06PM in Technology
Sometimes annoying requirement of string replacing will risen. everytime I forgotten how to do it so I leave this as my note. also there’s a JUnit test case.
Requirement
Assume we have following string literals. we have to convert input
string to expected
.
Solutions
Using numbered groups
Pattern p = Pattern.compile("(<a href=\")\\.\\./\\.\\./(.*)/(.*)/\""); Matcher matcher = p.matcher(input); String result = matcher.replaceAll("$1/entry/articles-$2-$3\"");
Using named groups
Pattern p = Pattern.compile("(?<prefix><a href=\")\\.\\./\\.\\./(?<category>.*)/(?<handle>.*)/\""); Matcher matcher = p.matcher(input); String result = matcher.replaceAll("${prefix}/entry/articles-${category}-${handle}\"");
Using Matcher#appendReplacement(). this one is most flexible.
Pattern p = Pattern.compile("(?<prefix><a href=\")(?<url>.*)\""); Matcher matcher = p.matcher(input); StringBuffer sb = new StringBuffer(); while (matcher.find()) { // any complex logic can be placed here String url = matcher.group("url"); String[] urls = url.split("/"); matcher.appendReplacement(sb, "${prefix}/entry/articles-" + urls[2] + "-" + urls[3] + "\""); } matcher.appendTail(sb); String result = sb.toString();
Escaping special character for replacement
$
have special meaning for replacement string, but sometimes we may need to use $
as just a literal. for such case, we can use Matcher.quoteReplacement()
for escaping $
character as follows:
String input = "../../jbatch/hello/"; String expected = "../../$1/${name}/"; Pattern p = Pattern.compile("(?<prefix>\\.\\./\\.\\.)/.*/.*/"); String result = p.matcher(input).replaceAll("${prefix}/" + Matcher.quoteReplacement("$1/${name}") + "/");
Tags: regex