尚方宝剑之说
我对这里的任何解决方案都不满意。我想要一个无状态的解决方案。如果替换字符串碰巧与模式匹配,我也不想陷入无限循环。在此期间,我增加了对limit参数和返回count参数的支持。(我使用AtomicInteger来模拟通过引用传递整数。)我将callback参数移到参数列表的末尾,以简化定义匿名类的过程。这是用法示例:final Map props = new HashMap();props.put("MY_NAME", "Kip");props.put("DEPT", "R&D");props.put("BOSS", "Dave");String subjectString = "Hi my name is ${MY_NAME} and I work in ${DEPT} for ${BOSS}";String sRegex = "\\$\\{([A-Za-z0-9_]+)\\}";String replacement = ReplaceCallback.replace(sRegex, subjectString, new ReplaceCallback.Callback() { public String matchFound(MatchResult match) { String group1 = match.group(1); if(group1 != null && props.containsKey(group1)) return props.get(group1); return match.group(); }});System.out.println("replacement: " + replacement);这是我的ReplaceCallback类的版本:import java.util.concurrent.atomic.AtomicInteger;import java.util.regex.*;public class ReplaceCallback{ public static interface Callback { /** * This function is called when a match is made. The string which was matched * can be obtained via match.group(), and the individual groupings via * match.group(n). */ public String matchFound(MatchResult match); } /** * Replaces with callback, with no limit to the number of replacements. * Probably what you want most of the time. */ public static String replace(String pattern, String subject, Callback callback) { return replace(pattern, subject, -1, null, callback); } public static String replace(String pattern, String subject, int limit, Callback callback) { return replace(pattern, subject, limit, null, callback); } /** * @param regex The regular expression pattern to search on. * @param subject The string to be replaced. * @param limit The maximum number of replacements to make. A negative value * indicates replace all. * @param count If this is not null, it will be set to the number of * replacements made. * @param callback Callback function */ public static String replace(String regex, String subject, int limit, AtomicInteger count, Callback callback) { StringBuffer sb = new StringBuffer(); Matcher matcher = Pattern.compile(regex).matcher(subject); int i; for(i = 0; (limit < 0 || i < limit) && matcher.find(); i++) { String replacement = callback.matchFound(matcher.toMatchResult()); replacement = Matcher.quoteReplacement(replacement); //probably what you want... matcher.appendReplacement(sb, replacement); } matcher.appendTail(sb); if(count != null) count.set(i); return sb.toString(); }}