当FreeMarker遇到正则表达式
需求描述
在编制 FreeMarker 模板文件时,我有一个需求,简单描述如下:
将一个表达式(expr)进行分解成多个token,每个token要么是一个标识符、要么不是,比如
当 expr = "name" 时,只包含一个token,即 ["name"];
当 expr = "name||name2" 时,可分解成3个token,即 ["name", "||", "name2"];
当 expr 就是一个 token 时,有一些特殊处理。
有问题的实现
于是,在 ftl 文件中,这样写道:
-
<#macroparseExpr1expr>
-
parse${expr}
-
<#assigntokens=expr?matches("[\\w]+|[^\\w]+")/>
-
<#listtokensastoken>
-
<#iftokens?size==1>
-
[${token}]
-
<#else>
-
[${token}]
-
</#if>
-
</#list>
-
</#macro>
-
-
<@parseExpr1expr="name"/>
-
<@parseExpr1expr="name||name2"/>
上面的代码在执行时会有异常抛出:
Exception in thread "main" java.lang.IllegalStateException: No match available
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)
如果注释掉第二个测试,就不会有问题。
-
<@parseExpr1expr="name"/>
-
<#--<@parseExpr1expr="name||name2"/>-->
parse name
[name]
也就是说,在 expr 能分解成多个 token 时,这种写法就会有问题。
无问题的实现
上面 tokens?size 是在循环中计算的,改成在循环外计算试试:
-
<#macroparseExpr2expr>
-
parse${expr}
-
<#assigntokens=expr?matches("[\\w]+|[^\\w]+"),count=tokens?size/>
-
<#listtokensastoken>
-
<#ifcount==1>
-
[${token}]
-
<#else>
-
[${token}]
-
</#if>
-
</#list>
-
</#macro>
-
-
<@parseExpr2expr="name"/>
-
<@parseExpr2expr="name||name2"/>
输出结果如下:
parse name
[name]
parse name||name2
[name]
[||]
[name2]
这样就没有问题了。从逻辑上讲,两个实现其实是等同的。这应该是 FreeMarker 在处理正则表达式的时候出现了问题。
测试用的 java 代码
-
importfreemarker.template.*;
-
importjava.util.*;
-
importjava.io.*;
-
-
publicclassTest{
-
-
publicstaticvoidmain(String[]args)throwsException{
-
-
-
-
-
-
Configurationcfg=newConfiguration();
-
cfg.setDirectoryForTemplateLoading(newFile("templates"));
-
cfg.setObjectWrapper(newDefaultObjectWrapper());
-
-
-
-
-
-
Templatetemp=cfg.getTemplate("test.ftl");
-
-
-
Maproot=newHashMap();
-
-
-
Writerout=newOutputStreamWriter(System.out);
-
temp.process(root,out);
-
out.flush();
-
}
-
-
}
分享到:
相关推荐
NULL 博文链接:https://zhenghuazhi.iteye.com/blog/1923544
f) 注:hudson.freemarker_ide是插件名称,0.9.14 是版本号,plugins/hudson.freemarker_ide_0.9.14/ 是插件存放目录,如果插件是个jar包则不用最后的“/”; 4,false 是Eclipse安装插件的默认模式 g) 退出Eclipse...
FreeMarker语法之表达式,FreeMarker如何生成静态页面,freemarker空值的多种处理方法,FreeMarker的优点和缺点,Freemarker的内置函数及用法
FreeMarker,FreeMarker
赠送jar包:freemarker-2.3.31.jar; 赠送原API文档:freemarker-2.3.31-javadoc.jar; 赠送源代码:freemarker-2.3.31-sources.jar; 赠送Maven依赖信息文件:freemarker-2.3.31.pom; 包含翻译后的API文档:...
赠送jar包:freemarker-2.3.30.jar; 赠送原API文档:freemarker-2.3.30-javadoc.jar; 赠送源代码:freemarker-2.3.30-sources.jar; 赠送Maven依赖信息文件:freemarker-2.3.30.pom; 包含翻译后的API文档:...
Freemarker页面语法 A 概念 最常用的 3 个概念 sequence 序列,对应java 里的list 、数组等非键值对的集合 hash 键值对的集合 namespace 对一个ftl 文件的引用, 利用这个名字可以访问到该ftl 文件的资源 ...
freemarker\Freemarker教程_中文版
freemarker freemarker freemarker freemarker freemarker freemarker freemarker freemarker
如果全用不存在的指令,FreeMarker不会使用模板输出,而是产生一个错误消息.FreeMarker会忽略FTL标签中的空白字符.值得注意的是, /> 和指令之间不允许有空白字符. 2, 插值规则 FreeMarker的插值有如下两种类型:1,...
FreeMarker
freemarker替换变量实例
camel-freemarker-1.6.4.jar, camel-freemarker-2.8.1.jar, com.springsource.freemarker-2.3.15.jar, com.springsource.freemarker-sources-2.3.15.jar, freemarker-1.4.1.jar, freemarker-2-3-18.jar, freemarker-...
Freemarker 实例,Freemarker 实例Freemarker 实例,Freemarker 实例
FreeMarker中文文档.pdf FreeMarker入门必修
FreeMarker手册-Freemarker 2.3.18。。。。。。。。。。。。。。。。。
注:hudson.freemarker_ide是插件名称,0.9.14 是版本号,plugins/hudson.freemarker_ide_0.9.14/ 是插件存放目录,如果插件是个jar包则不用最后的“/”; 4,false 是Eclipse安装插件的默认模式 。。。。。 退出...
freemarker格式化的eclipse插件。用于freemarker的格式化。
Freemarker模板生成pdf+javaFreemarker模板生成pdf+javaFreemarker模板生成pdf+javaFreemarker模板生成pdf+javaFreemarker模板生成pdf+java
FreeMarker api 2.3.16 FreeMarker api 2.3.16 FreeMarker api 2.3.16 FreeMarker api 2.3.16 FreeMarker api 2.3.16 FreeMarker api 2.3.16