package houlei.java.util; import java.util.Map; import java.lang.StringBuilder; /** * 可替换参数变量的字符串类。参数的形式为:${参数} * 例如:字符串 "This is a ${SomeThing}." 可替换的部分是:${SomeThing}。其中,SomeThing即为参数。
* 如果要将${SomeThing}替换为字符串"Demo"(也就是说替换后的字符串是:"This is a Demo."), * 我们可以将SomeThing和Demo组成键值对放入Map中进行转换。 * 代码示例:
*{@code * String demoStr = "This is a ${SomeThing}."; * DynamicString ds = new DynamicString(demoStr); * Map* 注意:反斜杠'/'是转义字符,活用可处理常见问题。 *param = new java.util.HashMap (4); * param.put("SomeThing", "Demo"); * System.out.println(ds.convert(param)); * } 该类创建于 2010-3-3 上午01:06:26 * @version 1.0.0 * @author 侯磊 */ public class DynamicString { private String dynStr; private DynamicPattern header; private DynamicPattern tail; static abstract class DynamicPattern { DynamicPattern next; public abstract Object subConvert(Map
pattern); } static class StringPattern extends DynamicPattern { private String pattern; public StringPattern(StringBuilder buff, int start, int end) { this.pattern = buff.substring(start, end); } @Override public Object subConvert(Map map) { return pattern; } } static class MappedPattern extends DynamicPattern { private String key; public MappedPattern(StringBuilder buff, int start, int end) { this.key = buff.substring(start, end); } @Override public Object subConvert(Map param) { if(param.get(key)==null){ throw new IllegalArgumentException("所传入的Map中,不含有参数:"+key); } return param.get(key); } } /**可替换参数变量的字符串类。该类适用于多个参数的情况。 * @param dynStr 模板字符串。 */ public DynamicString(String dynStr) { this.dynStr = dynStr; init(); } /** * 生成中间模板,转义字符也要考虑在内。 */ private void init() { header = tail = null; StringBuilder buff = new StringBuilder(dynStr); int start = 0, ptr = 0; boolean noMatching = true; for (ptr = start; ptr < buff.length(); ptr++) { if(buff.charAt(ptr)=='$' && buff.charAt(ptr+1)=='{'){ if(ptr>0 && buff.charAt(ptr-1)=='//'){ buff.deleteCharAt(ptr---1); if(ptr>1 && buff.charAt(ptr-1)=='//' && buff.charAt(ptr-2)=='//'){ buff.deleteCharAt(ptr---1);continue; } if(!(ptr>0 && buff.charAt(ptr-1)=='//')) continue; } noMatching=false; StringPattern sp = new StringPattern(buff, start, ptr); appendPattern(sp); start = ptr+2; for (ptr += 2; ptr < buff.length(); ptr++) { if (buff.charAt(ptr) == '}') { if(buff.charAt(ptr-1)=='//'){ buff.deleteCharAt(ptr---1); if(buff.charAt(ptr-1)!='//') continue; } MappedPattern mp = new MappedPattern(buff, start, ptr); appendPattern(mp); noMatching=true; start = ++ptr;break; } } } } if (noMatching && ptr <= buff.length()) appendPattern(new StringPattern(buff, start, ptr)); } private DynamicString appendPattern(DynamicPattern pattern) { if (header == null) { header = pattern; tail = header; } else { tail.next = pattern; tail = pattern; } return this; } /**传入参数变量,得到替换后的结果。 * @param param 将替换的参数及变量以键值对的形式存放到Map对象中。 * @return 返回替换回的结果。 * @exception IllegalArgumentException 当待替换的参数不在Map对象中时,抛出该异常。 */ public String convert(Map param) { if (header == null) return null; DynamicPattern ptr = header; StringBuilder sb = new StringBuilder(); while (ptr != null) { sb.append(ptr.subConvert(param)); ptr = ptr.next; } return sb.toString(); } /** * @see #convert(Map) */ public String convert(String key,String value){ Map param = new java.util.HashMap (2); param.put(key, value); return convert(param); } }
真是相当有用啊