Skip to content

Instantly share code, notes, and snippets.

@lzxz1234
Last active June 8, 2017 02:17
Show Gist options
  • Save lzxz1234/3984341 to your computer and use it in GitHub Desktop.
Save lzxz1234/3984341 to your computer and use it in GitHub Desktop.
模版解析进行String字符串组装
public class StringTemplate {
private List<Element> list = new ArrayList<Element>();
private StringTemplate(List<Element> list) {
this.list = list;
}
/**
* @param src 例:尊敬的${who}用户,您该月话费为${amount}元,谢谢${2}!!
* @return 解析生成的模版,调用 <code>replace</code> 方法即可生成结果
*/
public static StringTemplate compile(String src) {
List<Element> list = new ArrayList<Element>();
final char[] cs = src.toCharArray();
int index1 = 0, index2 = 0;
while(true) {
index2 = next(cs, index1, '$');
if(index2 != -1 && index2 < cs.length - 1) {
if(cs[index2 + 1] == '{') {
list.add(new AppendElement(cs, index1, index2 - index1));
index1 = index2 + 2;
index2 = next(cs, index1, '}');
list.add(new ReplaceElement(new String(cs, index1, index2 - index1)));
index1 = index2 + 1;
} else {
list.add(new AppendElement(cs, index1, index2 - index1 + 1));
index1 = index2 + 1;
}
} else {
break;
}
}
list.add(new AppendElement(cs, index1, cs.length - index1));
return new StringTemplate(list);
}
/**
* @param replacements
* @return 根据模版生成字符串,变量均按replacements中同key值替换
*/
public String replace(ReplaceHolder replacements) {
StringBuilder sb = new StringBuilder();
for(Element ele : list) {
ele.append(sb, replacements);
}
return sb.toString();
}
public String replace(final Map<String, Object> map) {
return this.replace(new ReplaceHolder() {
@Override
public String get(String key) {
Object result = map.get(key);
if(result != null) {
if(result.getClass().isArray())
return ArrayUtils.toString(result);
return result.toString();
}
String[] keyPath = key.split("\\.");
result = map.get(keyPath[0]);
for(int i = 1; i < keyPath.length; i ++)
try {
if(result == null) return "";
result = MethodUtils.getGetter(result.getClass(), keyPath[i]).invoke(result);
} catch (Exception e) {
throw new RuntimeException("路径错误" + key, e);
}
return result == null ? "" : result.toString();
}
});
}
private static int next(char[] cs, int begin, char dest) {
for(int i = begin; i < cs.length; i ++) {
if(cs[i] == dest) {
return i;
}
}
return -1;
}
private static abstract class Element {
abstract void append(StringBuilder sb, ReplaceHolder map);
}
private static class AppendElement extends Element {
private char[] cs;
private int index;
private int length;
AppendElement(char[] cs, int index, int length) {
this.cs = cs;
this.index = index;
this.length = length;
}
@Override
void append(StringBuilder sb, ReplaceHolder map) {
sb.append(cs, index, length);
}
}
private static class ReplaceElement extends Element {
private String key;
ReplaceElement(String key) {
this.key = key;
}
@Override
void append(StringBuilder sb, ReplaceHolder map) {
String replaceStr = map.get(key);
sb.append(replaceStr == null ? "" : replaceStr);
}
}
public static interface ReplaceHolder {
public String get(String key);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment