Yis*_*hai 9 java regex stringtokenizer
给出一个像这样的字符串:
Hello {FIRST_NAME}, this is a personalized message for you.
Run Code Online (Sandbox Code Playgroud)
FIRST_NAME是一个任意标记(传递给方法的地图中的一个键),编写一个例程,将该字符串转换为:
Hello Jim, this is a personalized message for you.
Run Code Online (Sandbox Code Playgroud)
给出了一张带有FIRST_NAME条目的地图 - > Jim.
似乎StringTokenizer是最直接的方法,但Javadocs真的说你应该更喜欢使用正则表达式aproach.你会如何在基于正则表达式的解决方案中做到这一点?
Yis*_*hai 11
谢谢大家的答案!
Gizmo的答案绝对是开箱即用的,也是一个很好的解决方案,但遗憾的是不适合,因为格式不能局限于Formatter类在这种情况下的作用.
Adam Paynter真正了解问题的核心,采用正确的模式.
Peter Nix和Sean Bright有一个很好的解决方法来避免正则表达式的所有复杂性,但是如果有不好的令牌,那么我需要提出一些错误.
但就完成正则表达式和合理的替换循环而言,这是我提出的答案(谷歌和现有答案的一点帮助,包括Sean Bright关于如何使用group(1)vs group()的评论):
private static Pattern tokenPattern = Pattern.compile("\\{([^}]*)\\}");
public static String process(String template, Map<String, Object> params) {
StringBuffer sb = new StringBuffer();
Matcher myMatcher = tokenPattern.matcher(template);
while (myMatcher.find()) {
String field = myMatcher.group(1);
myMatcher.appendReplacement(sb, "");
sb.append(doParameter(field, params));
}
myMatcher.appendTail(sb);
return sb.toString();
}
Run Code Online (Sandbox Code Playgroud)
doParameter从地图中获取值并将其转换为字符串,如果不存在则抛出异常.
另请注意,我更改了模式以查找空括号(即{}),因为这是显式检查的错误条件.
编辑:请注意,appendReplacement与字符串的内容无关.根据javadoc,它将$和反斜杠识别为一个特殊字符,因此我添加了一些转义来处理上面的示例.没有以最具性能意识的方式完成,但在我的情况下,值得尝试微量优化字符串创建并不是一件足够大的事情.
感谢Alan M的评论,可以更简单地避免appendReplacement的特殊字符问题.
String.replaceAll("{FIRST_NAME}", actualName);
Run Code Online (Sandbox Code Playgroud)
在这里查看javadocs .
尝试这个:
注意:作者的最终解决方案基于此示例,并且更加简洁。
public class TokenReplacer {
private Pattern tokenPattern;
public TokenReplacer() {
tokenPattern = Pattern.compile("\\{([^}]+)\\}");
}
public String replaceTokens(String text, Map<String, String> valuesByKey) {
StringBuilder output = new StringBuilder();
Matcher tokenMatcher = tokenPattern.matcher(text);
int cursor = 0;
while (tokenMatcher.find()) {
// A token is defined as a sequence of the format "{...}".
// A key is defined as the content between the brackets.
int tokenStart = tokenMatcher.start();
int tokenEnd = tokenMatcher.end();
int keyStart = tokenMatcher.start(1);
int keyEnd = tokenMatcher.end(1);
output.append(text.substring(cursor, tokenStart));
String token = text.substring(tokenStart, tokenEnd);
String key = text.substring(keyStart, keyEnd);
if (valuesByKey.containsKey(key)) {
String value = valuesByKey.get(key);
output.append(value);
} else {
output.append(token);
}
cursor = tokenEnd;
}
output.append(text.substring(cursor));
return output.toString();
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
12289 次 |
最近记录: |