通过好奇心,有没有办法用Java Stream写这个?
private final static Pattern decodePattern = Pattern.compile("&#(\\d+);");
StringBuffer buf = new StringBuffer();
Matcher m = decodePattern.matcher(somestring);
while (m.find()) {
m.appendReplacement(buf, String.valueOf((char) Integer.parseInt(m.group(1))));
}
m.appendTail(buf);
String decodeString = buf.toString();
答案 0 :(得分:2)
清除代码可以通过Matcher类中的Java 9方法重载来实现:
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模式和匹配器类中,在流支持方面没有太大变化。只有Pattern收到了public Stream<String> splitAsStream(CharSequence input)
方法,但是它创建了一个元素流,其中pattern表示我们要分割的 delimiter ,而不是我们想要找到的文本。 / p>
如果你想简化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
。