Java 9
在Java 9 中重载Matcher 类的方法可以实现更简洁的代码:
public String replaceAll(Function<MatchResult,String> replacer)。基本上我们现在可以替换像
这样的代码
StringBuffer sb = new StringBuffer();
while(matcher.find()){
matcher.appendReplacement(sb, /*create replacement*/);
}
matcher.appendTail(sb);
String result = sb.toString;
与
String replaced = matcher.replaceAll(match -> /*create replacement*/);
例如
String replaced = Pattern.compile("\\b\\w")
.matcher("foo bar baz")
.replaceAll(match -> match.group().toUpperCase());
//replaced: "Foo Bar Baz"
还增加了对匹配模式的元素流的支持:public Stream<MatchResult> results(),但 IMO 你的循环看起来不太适合流。即使使用results(),您的代码也会如下所示:
//BTW Java 9 provides support for StringBuilder beside StringBuffer
//for appendReplacement/appendTail
Matcher matcher = ...
StringBuilder buf = new StringBuilder();
matcher.results()
.map(result -> String.valueOf((char) Integer.parseInt(result.group(1))) )
.forEach(replacement -> matcher.appendReplacement(buf, replacement));
matcher.appendTail(buf);
String decodeString = buf.toString();
所以它看起来不太干净。
Java 8
在 Java 8 中,Pattern 和 Matcher 类在流支持方面没有太大变化。只有 Pattern 接收到 public Stream<String> splitAsStream(CharSequence input) 方法,但它创建了元素流,其中 pattern 表示我们要拆分的 delimiter,而不是我们要查找的文本。
如果您想在 Java 8 中简化代码,请编写您自己的方法,在该方法中您将提供 Matcher 和将匹配的内容(最好由 MatchResult 或 Matcher 表示,以便它可以访问 group(...) 方法)映射到替换应该代替它。
这种方法可能如下所示:
public static String replaceMatches(Matcher m, Function<MatchResult, String> mapping){
StringBuffer sb = new StringBuffer();
while(m.find()){
MatchResult matchResult = m.toMatchResult();
m.appendReplacement(sb, mapping.apply(matchResult));
}
m.appendTail(sb);
return sb.toString();
}
你可以像这样使用它:
Pattern p = Pattern.compile("\\b\\w");
Matcher m = p.matcher("foo bar baz");
String result = replaceMatches(m, mr -> mr.group().toUpperCase());
System.out.println(result);
结果:Foo Bar Baz。