当FreeMarker遇到正则表达式,Bug就出现了
当FreeMarker遇到正则表达式需求描述
在编制 FreeMarker 模板文件时,我有一个需求,简单描述如下:
将一个表达式(expr)进行分解成多个token,每个token要么是一个标识符、要么不是,比如
当 expr = "name" 时,只包含一个token,即 ["name"];
当 expr = "name||name2" 时,可分解成3个token,即 ["name", "||", "name2"];
当 expr 就是一个 token 时,有一些特殊处理。
?
有问题的实现于是,在 ftl 文件中,这样写道:
?
?
? ? ? ? at java.util.regex.Matcher.start(Matcher.java:325)
? ? ? ? at freemarker.core.RegexBuiltins$RegexMatchModel$Match.<init>(RegexBuiltins.java:350)
? ? ? ? at freemarker.core.RegexBuiltins$RegexMatchModel$2.next(RegexBuiltins.java:339)
? ? ? ? at freemarker.core.IteratorBlock$Context.runLoop(IteratorBlock.java:164)
? ? ? ? at freemarker.core.Environment.visit(Environment.java:428)
? ? ? ? at freemarker.core.IteratorBlock.accept(IteratorBlock.java:102)
? ? ? ? at freemarker.core.Environment.visit(Environment.java:221)
? ? ? ? at freemarker.core.MixedContent.accept(MixedContent.java:92)
? ? ? ? at freemarker.core.Environment.visit(Environment.java:221)
? ? ? ? at freemarker.core.Macro$Context.runMacro(Macro.java:172)
? ? ? ? at freemarker.core.Environment.visit(Environment.java:614)
? ? ? ? at freemarker.core.UnifiedCall.accept(UnifiedCall.java:106)
? ? ? ? at freemarker.core.Environment.visit(Environment.java:221)
? ? ? ? at freemarker.core.MixedContent.accept(MixedContent.java:92)
? ? ? ? at freemarker.core.Environment.visit(Environment.java:221)
? ? ? ? at freemarker.core.Environment.process(Environment.java:199)
? ? ? ? at freemarker.template.Template.process(Template.java:259)
? ? ? ? at Test.main(Test.java:28)?
?
如果注释掉第二个测试,就不会有问题。
?
?
import freemarker.template.*;import java.util.*;import java.io.*; public class Test { public static void main(String[] args) throws Exception { /* ------------------------------- */ /* You should do this ONLY ONCE in the whole application life-cycle: */ /* Create and adjust the configuration */ Configuration cfg = new Configuration(); cfg.setDirectoryForTemplateLoading(new File("templates")); cfg.setObjectWrapper(new DefaultObjectWrapper()); /* ------------------------------- */ /* You usually do these for many times in the application life-cycle: */ /* Get or create a template */ Template temp = cfg.getTemplate("test.ftl"); /* Create a data-model */ Map root = new HashMap(); /* Merge data-model with template */ Writer out = new OutputStreamWriter(System.out); temp.process(root, out); out.flush(); } }??
?