On this page
内置字符串
Page Contents
这些内置函数作用于字符串的左值。但是,如果左值是数字或日期/时间/日期时间或布尔值(从 2.3.20 开始),它将根据当前的数字,日期/时间/日期时间和布尔格式自动转换为字符串设置(与使用${...}
插入此类值时所应用的格式程序相同)。
boolean
字符串转换为布尔值。该字符串必须为true
或false
(区分大小写!),或必须采用boolean_format
设置指定的格式。
如果字符串格式不正确,则当您尝试访问此内置文件时,将出错并中止模板处理。
cap_first
字符串首个单词大写的字符串。有关“单词”的确切含义,请参见word_list built-in。例:
${" green mouse"?cap_first}
${"GreEN mouse"?cap_first}
${"- green mouse"?cap_first}
The output:
Green mouse
GreEN mouse
- green mouse
在"- green mouse"
的情况下,第一个单词是-
。
capitalize
所有单词都大写的字符串。有关“单词”的确切含义,请参见word_list built-in。例:
${" green mouse"?capitalize}
${"GreEN mouse"?capitalize}
The output:
Green Mouse
Green Mouse
chop_linebreak
如果有换行符,则在结尾处没有line-break的字符串,否则为未更改的字符串。
contains
Note:
从 FreeMarker 2.3.1 开始可以使用此内置功能。它在 2.3 中不存在。
返回子字符串是否指定为字符串中此内置事件的参数。例如:
<#if "piceous"?contains("ice")>It contains "ice"</#if>
这将输出:
It contains "ice"
日期,时间,日期时间
字符串值转换为日期,时间或日期时间值。它将期望由date_format,time_format 和 datetime_format 设置指定的格式。如果字符串格式不正确,则当您尝试访问此内置文件时,将出错并中止模板处理。
<#-- The date_format, time_format and datetime_format settings must match this format! -->
<#assign someDate = "Oct 25, 1995"?date>
<#assign someTime = "3:05:30 PM"?time>
<#assign someDatetime = "Oct 25, 1995 03:05:00 PM"?datetime>
<#-- Changing the setting value changes the expected format: -->
<#setting datetime_format="iso">
<#assign someDatetime = "1995-10-25T15:05"?datetime>
您还可以显式指定格式,例如?datetime.format
(因此也可以指定为?datetime["format"]
)或?datetime("format")
;这三种形式都一样。也可以使用?date
和?time
类似地指定格式。有关格式值的语法和含义,请参见date_format,time_format 和 datetime_format 设置的可能值。例:
<#-- Parsing XML Schema xs:date, xs:time and xs:dateTime values: -->
<#assign someDate = "1995-10-25"?date.xs>
<#assign someTime = "15:05:30"?time.xs>
<#assign someDatetime = "1995-10-25T15:05:00"?datetime.xs>
<#-- Parsing ISO 8601 (both extended and basic formats): -->
<#assign someDatetime = "1995-10-25T15:05"?datetime.iso>
<#assign someDatetime = "19951025T1505"?datetime.iso>
<#-- Parsing with SimpleDateFormat patterns: -->
<#assign someDate = "10/25/1995"?date("MM/dd/yyyy")>
<#assign someTime = "15:05:30"?time("HH:mm:ss")>
<#assign someDatetime = "1995-10-25 03:05 PM"?datetime("yyyy-MM-dd hh:mm a")>
<#-- Parsing with custom date formats: -->
<#assign someDatetime = "October/25/1995 03:05 PM"?datetime.@worklog>
为避免误解,左侧值不必为字符串 Literals。例如,当您从 XML DOM 读取数据时(所有值都是未解析的字符串),您可以执行order.confirmDate?date.xs
之类的操作来将字符串值转换为实际日期。
当然,格式也可以是变量,例如"..."?datetime(myFormat)
。
请注意,从 2.3.24 版本开始,也可以使用 0 个参数(例如?date()
)来调用这些内置函数。它几乎与只写?date
相同。区别是高度技术性的,几乎无关紧要:?date()
和此类返回与日期解析器(freemarker.core.TemplateDateFormat
实现)返回的 Java 对象完全相同,而没有()
的?date
返回一个棘手的包装值,该值是日期,并且方法和哈希同时。
ends_with
返回此字符串是否以参数中指定的子字符串结尾。例如"ahead"?ends_with("head")
返回布尔值true
。同样,"head"?ends_with("head")
将返回true
。
ensure_ends_with
Note:
从 FreeMarker 2.3.21 开始,此内置功能可用。
如果字符串不以指定为第一参数的子字符串结尾,则将其添加到字符串之后,否则返回原始字符串。例如,"foo"?ensure_ends_with("/")
和"foo/"?ensure_ends_with("/")
都返回"foo/"
。
ensure_starts_with
Note:
从 FreeMarker 2.3.21 开始,此内置功能可用。
如果字符串不是以指定为第一个参数的子字符串开头,则将其添加到字符串之前,否则返回原始字符串。例如,"foo"?ensure_starts_with("/")
和"/foo"?ensure_starts_with("/")
都返回"/foo"
。
如果指定两个参数,则将第一个参数解释为 Java 正则表达式,如果它与字符串的开头不匹配,则将指定为第二个参数的字符串添加到字符串之前。例如someURL?ensure_starts_with("[a-zA-Z]+://", "http://")
将检查字符串是否以与"[a-zA-Z]+://"
匹配的东西开头(请注意,不需要^
),如果不需要,则在"http://"
之前加上前缀。
此方法还接受第三个flags parameter。由于使用 2 个参数进行调用意味着在其中"r"
(即正则表达式模式),因此您很少需要此参数。一种值得注意的情况是,当您不希望将第一个参数解释为正则表达式时,仅将其解释为纯文本,而又希望比较不区分大小写,在这种情况下,您应使用"i"
作为第三个参数。
esc
Note:
从 FreeMarker 2.3.24 开始,此内置功能可用。
使用当前的output format来转义该值,并防止返回值auto-escaping(以避免两次转义)。由于具有自动转义功能,因此通常仅在禁用自动转义功能时才需要此功能:
<#ftl output_format="HTML" auto_esc=false>
<#assign s = "R&D">
${s}
${s?esc}
R&D
R&D
在启用自动转义的模板中,使用它是多余的:
<#ftl output_format="HTML">
<#assign s = "R&D">
${s}
${s?esc} <#-- ?esc is redundant here -->
R&D
R&D
通过将字符串值转换为标记输出值,使用当前输出格式转义字符串并将结果用作标记,该内置函数起作用。最终的标记输出值在调用时属于当前输出格式。
只要 Importing 的标记输出值属于当前输出格式,此内置函数也可以应用于标记输出值,它将跳过而不会更改。如果不是这样,则必须将标记转换为当前的输出格式,当前(从 2.3.24 版本开始)只有在通过转义纯文本(通常使用?esc
)创建该值时才会成功。
当前输出格式为非标记输出格式时,不能使用此内置函数。尝试这样做将导致parse-time error。
此内置与已弃用的转义和无意指令无关。实际上,解析器将阻止在同一位置使用它们,以防止混淆。
groups
仅与内置matches
的结果一起使用。见there...
html (deprecated)
Note:
2.3.24 中引入的auto-escaping mechanism不推荐使用此内置函数。通常,为了防止双重转义和混乱,在启用自动转义的地方使用此内置符号是parse-time error。为了帮助迁移,此内置插件无提示地绕过 HTML 标记输出值而不更改它们。
字符串作为 HTML 标记。也就是说,所有字符串:
<
替换为<
>
替换为>
&
替换为&
"
替换为"
'
被'
替换如果程序员具有设置 incompatible_improvements 设置到 2.3.24 或更高版本(也将其设置为 2.3.20 或更高并且您不在字符串 Literals 范围内)。否则'
不会被替换,因此您必须使用引号("
而不是'
)引用要安全插入值的属性值。
<input type=text name=user value="${user?html}">
Warning!
插入属性值时,请始终引用该属性,否则攻击者可能会利用它!这是错误的:<input name="user" value=${user?xhtml}>
。很好:<input name="user" value="${user?xhtml}">
。
请注意,在 HTML 页面中,通常要对所有插值使用此内置函数。您可以使用escape directive节省大量键入时间,并减少意外错误的可能性。
index_of
返回指定子字符串首次出现在该字符串中的索引。例如,"abcabc"?index_of("bc")
将返回 1(不要忘记第一个字符的索引为 0)。另外,您可以指定从以下位置开始搜索的索引:"abcabc"?index_of("bc", 2)
将返回 4.第二个参数的数值没有限制:如果为负数,则其效果与零相同,并且为零。大于此字符串的长度,则具有与等于此字符串的长度相同的效果。十进制值将被截断为整数。
如果第一个参数未在该字符串中作为子字符串出现(如果使用第二个参数,则从给定索引开始),则它返回-1.
j_string
使用 Java 语言字符串 Literals 的转义规则对字符串进行转义,因此将值插入字符串 Literals 中是安全的。请注意,它将不在插入值周围添加引号;您打算在字符串 Literals 中使用此* inside *。
UCS代码点 0x20 下的所有字符都将被转义。如果它们在 Java 语言中没有专用的转义序列(例如\n
,\t
等),则将它们替换为 UNICODE 转义(\uXXXX
)。
Example:
<#assign beanName = 'The "foo" bean.'>
String BEAN_NAME = "${beanName?j_string}";
will output:
String BEAN_NAME = "The \"foo\" bean.";
js_string
使用 JavaScript 语言字符串 Literals 的转义规则对字符串进行转义,因此将值插入字符串 Literals 中是安全的。请注意,它将不在插入值周围添加引号;您打算在字符串 Literals 中使用此* inside *。
Warning!
当插入 HTML 属性中的 JavaScript 字符串 Literals 时,还必须使用 HTML 转义符对值进行转义。因此,您中没有自动 HTML 转义,这是 WRONG:<p onclick="alert('${message?js_string}')">
,这很不错:<p onclick="alert('${message?js_string?html}')">
。
Example:
<#assign user = "Big Joe's \"right hand\"">
<script>
alert("Welcome ${user?js_string}!");
</script>
will output:
<script>
alert("Welcome Big Joe\'s \"right hand\"!");
</script>
确切的转义规则是:
"
以\"
的形式转义'
以\'
的形式转义\
以\\
的形式转义如果
/
在转义字符串中<
的正后方,或者在转义字符串的开头,则/
被转义为\/
如果
>
直接位于转义字符串中]]
或--
的后面,或者它位于转义字符串的开头,或者如果在转义字符串的开头仅存在]
或-
,则>
被转义为\>
<
如果在转义字符串中紧跟着?
或!
,或者在转义字符串的末尾,则以\u003C
进行转义UCS代码点范围 U 0000 ... U 001f 和 U 007f ... U 009f 中的控制字符转义为
\r
,\n
等,或者转为\xXX
,在 JavaScript 中没有特殊转义。具有UCS代码点 U 2028(行分隔符)和 U 2029(段落分隔符)的控制字符将作为
\uXXXX
进行转义,因为它们是 ECMAScript 中的源代码换行符。
json_string
使用 JSON 语言字符串 Literals 的转义规则对字符串进行转义,因此将值插入字符串 Literals 中是安全的。请注意,它将不在插入值周围添加引号;您打算在字符串 Literals 中使用此* inside *。
这不会转义'
个字符,因为 JSON 字符串必须用"
引起来。
转义规则与记录为 js_string几乎相同。不同之处在于,根本不对'
进行转义,对>进行转义为\ u003E(而不作为>),并且使用\uXXXX
转义代替了\xXX
转义。
keep_after
Note:
从 FreeMarker 2.3.21 开始,此内置功能可用。
删除第一次出现给定子字符串之后的字符串部分。例如:
${"abcdefgh"?keep_after("de")}
will print
fgh
如果找不到参数字符串,它将返回一个空字符串。如果参数字符串是长度为 0 的字符串,它将返回原始字符串不变。
此方法接受可选的flags parameter作为其第二个参数:
${"foo : bar"?keep_after(r"\s*:\s*", "r")}
will print
bar
keep_after_last
Note:
从 FreeMarker 2.3.22 开始,此内置功能可用。
与keep_after相同,但保留 Component 在参数的最后一次出现之后,而不是在第一次出现之后。例:
${"foo.bar.txt"?keep_after_last(".")}
will print
txt
而使用keep_after
,您将获得bar.txt
。
keep_before
Note:
从 FreeMarker 2.3.21 开始,此内置功能可用。
删除以给定子字符串开头的字符串部分。例如:
${"abcdef"?keep_before("de")}
will print
abc
如果没有找到参数字符串,它将返回原始字符串不变。如果参数字符串是长度为 0 的字符串,它将返回一个空字符串。
此方法接受可选的flags parameter作为其第二个参数:
${"foo : bar"?keep_before(r"\s*:\s*", "r")}
will print
foo
keep_before_last
Note:
从 FreeMarker 2.3.22 开始,此内置功能可用。
与keep_before相同,但是将 Component 保留在最后一次出现参数之前,而不是在第一次出现之后。例:
${"foo.bar.txt"?keep_before_last(".")}
will print
foo.bar
而使用keep_before
,您将获得foo
。
last_index_of
返回指定子字符串的最后一个(最右边)出现在此字符串内的索引。它返回子字符串的第一个(最左边)字符的索引。例如:"abcabc"?last_index_of("ab")
将返回 3.此外,您可以指定索引以开始搜索。例如,"abcabc"?last_index_of("ab", 2)
将返回 0.请注意,第二个参数指示子字符串开头的最大索引。第二个参数的数值没有限制:如果为负数,则具有与零相同的效果;如果它大于此字符串的长度,则与具有第二个参数的效果相同。等于此字符串的长度。十进制值将被截断为 inegers。
如果第一个参数未在该字符串中作为子字符串出现(在给定索引之前,如果使用第二个参数),则它返回-1.
left_pad
Note:
从 FreeMarker 2.3.1 开始可以使用此内置功能。
如果它与 1 个参数一起使用,则它将在字符串的开头插入空格,直到达到指定为参数的长度为止。如果字符串已经等于或大于指定的长度,则它将不执行任何操作。例如,这:
[${""?left_pad(5)}]
[${"a"?left_pad(5)}]
[${"ab"?left_pad(5)}]
[${"abc"?left_pad(5)}]
[${"abcd"?left_pad(5)}]
[${"abcde"?left_pad(5)}]
[${"abcdef"?left_pad(5)}]
[${"abcdefg"?left_pad(5)}]
[${"abcdefgh"?left_pad(5)}]
将输出以下内容:
[ ]
[ a]
[ ab]
[ abc]
[ abcd]
[abcde]
[abcdef]
[abcdefg]
[abcdefgh]
如果它与 2 个参数一起使用,则第一个参数的含义与您仅使用带有 1 个参数的内置参数的含义相同,而第二个参数则指定要插入的内容而不是空格字符。例如:
[${""?left_pad(5, "-")}]
[${"a"?left_pad(5, "-")}]
[${"ab"?left_pad(5, "-")}]
[${"abc"?left_pad(5, "-")}]
[${"abcd"?left_pad(5, "-")}]
[${"abcde"?left_pad(5, "-")}]
将输出以下内容:
[-----]
[----a]
[---ab]
[--abc]
[-abcd]
[abcde]
第二个参数可以是长度大于 1 的字符串。然后将定期插入该字符串,例如:
[${""?left_pad(8, ".oO")}]
[${"a"?left_pad(8, ".oO")}]
[${"ab"?left_pad(8, ".oO")}]
[${"abc"?left_pad(8, ".oO")}]
[${"abcd"?left_pad(8, ".oO")}]
将输出以下内容:
[.oO.oO.o]
[.oO.oO.a]
[.oO.oOab]
[.oO.oabc]
[.oO.abcd]
第二个参数必须是字符串值,并且必须至少包含 1 个字符。
length
字符串中的字符数。
lower_case
字符串的小写版本。例如"GrEeN MoUsE"?lower_case
将是"green mouse"
。
matches
这是内置的“超级用户”。如果您不知道regular expressions,请忽略它。
此内置函数确定字符串是否与模式完全匹配。同样,它返回匹配子字符串的列表。返回值是一个多类型值:
布尔值:
true
,如果整个字符串与模式匹配,则为false
。例如,"fooo"?matches('fo*')
是true
,但是"fooo bar"?matches('fo*')
是false
。序列:字符串的匹配子字符串列表。长度序列可能为 0.
For example:
<#if "fxo"?matches("f.?o")>Matches.<#else>Does not match.</#if>
<#assign res = "foo bar fyo"?matches("f.?o")>
<#if res>Matches.<#else>Does not match.</#if>
Matching sub-strings:
<#list res as m>
- ${m}
</#list>
will print:
Matches.
Does not match.
Matching sub-strings:
- foo
- fyo
如果正则表达式包含组(括号),则可以使用内置的groups
来访问它们:
<#-- Entire input match -->
<#assign res = "John Doe"?matches(r"(\w+) (\w+)")>
<#if res> <#-- Must not try to access groups if there was no match! -->
First name: ${res?groups[1]}
Second name: ${res?groups[2]}
</#if>
<#-- Subtring matches -->
<#assign res = "aa/rx; ab/r;"?matches("(.+?)/*(.+?);")>
<#list res as m>
- "${m}" is "${m?groups[1]}" per "${m?groups[2]}"
</#list>
这将打印:
First name: John
Second name: Doe
- "aa/rx;" is "a" per "a/rx"
- " ab/r;" is " " per "ab/r"
有关groups
内置行为的注意事项:
它既适用于子字符串匹配,也适用于整个字符串匹配的结果(如上例所示)
groups
返回的序列中的第一项是正则表达式匹配的整个子字符串。因此,第一个显式正则表达式组的索引(换句话说,正则表达式中第一个(...)
的索引)为 1,而不是 0.而且,因此,序列的大小比的数目大一个。显式正则表达式组。groups
返回的序列的大小仅取决于正则表达式中显式组的数量,因此即使未找到正则表达式也将相同(非 0)。匹配时尝试访问序列中的某个项目(如res?groups[1]
)将导致错误。因此,在访问组之前,应始终检查是否存在任何匹配项(如<#if res>access the groups here</#if>
)。如果正则表达式匹配,但正则表达式中的某个显式组不匹配,则该序列的序列将包含一个长度为 0 的字符串。因此,只要包含的正则表达式已匹配某些内容,访问不匹配的组是安全的。
matches
接受可选的第二个参数flags。请注意,它不支持标志f
,并且会忽略r
标志。
no_esc
Note:
从 FreeMarker 2.3.24 开始,此内置功能可用。
防止值的auto-escaping。例如:
<#ftl output_format="HTML">
<#assign s = "<b>Test</b>">
${s}
${s?no_esc}
<b>Test</b>
<b>Test</b>
这是通过将字符串值转换为标记输出值来实现的,该字符串原样使用该字符串作为标记,并且在调用时属于当前output format。
只要 Importing 标记输出值属于当前输出格式,此内置函数也可以应用于标记输出值,它会绕过而不会更改。如果不是这样,则必须将标记转换为当前的输出格式,当前(从 2.3.24 版本开始)只有在通过转义纯文本(通常使用?esc
)创建该值时才会成功。
当前输出格式为非标记输出格式时,不能使用此内置函数。尝试这样做将导致parse-time error。
此内置与已弃用的转义和无意指令无关。实际上,解析器将阻止在同一位置使用它们,以防止混淆。
number
字符串转换为数值。该数字必须为“计算机语言”格式。也就是说,它必须采用与语言环境无关的形式,其中小数点分隔符是点,并且没有分组。
该内置功能可识别 FreeMarker 模板语言使用的格式的数字。另外,它识别科学计数法(例如"1.23E6"
,"1.5e-8"
)。从 FreeMarker 2.3.21 开始,它还可以识别所有 XML Schema 数字格式,例如NaN
,INF
,-INF
以及 Java 本地格式Infinity
和-Infinity
。
如果字符串格式不正确,则当您尝试访问此内置文件时,将出错并中止模板处理。
实际上,该字符串是通过当前arithmetic_engine
的toNumber
方法(配置设置)进行解析的。但是,该方法的行为应与上述类似。
replace
它用于将原始字符串中所有出现的字符串替换为另一个字符串。它不处理单词边界。例如:
${"this is a car acarus"?replace("car", "bulldozer")}
will print:
this is a bulldozer abulldozerus
替换按从左到右的 Sequences 进行。这意味着:
${"aaaaa"?replace("aaa", "X")}
will print:
Xaa
如果第一个参数是一个空字符串,则所有出现的空字符串都将被替换,就像"foo"?replace("","|")
的值等于"|f|o|o|"
。
replace
接受可选的flags parameter作为其第三个参数。
right_pad
Note:
从 FreeMarker 2.3.1 开始可以使用此内置功能。它在 2.3 中不存在。
这与left_pad相同,但是它将字符插入到字符串的末尾而不是字符串的开头。
Example:
[${""?right_pad(5)}]
[${"a"?right_pad(5)}]
[${"ab"?right_pad(5)}]
[${"abc"?right_pad(5)}]
[${"abcd"?right_pad(5)}]
[${"abcde"?right_pad(5)}]
[${"abcdef"?right_pad(5)}]
[${"abcdefg"?right_pad(5)}]
[${"abcdefgh"?right_pad(5)}]
[${""?right_pad(8, ".oO")}]
[${"a"?right_pad(8, ".oO")}]
[${"ab"?right_pad(8, ".oO")}]
[${"abc"?right_pad(8, ".oO")}]
[${"abcd"?right_pad(8, ".oO")}]
这将输出以下内容:
[ ]
[a ]
[ab ]
[abc ]
[abcd ]
[abcde]
[abcdef]
[abcdefg]
[abcdefgh]
[.oO.oO.o]
[aoO.oO.o]
[abO.oO.o]
[abc.oO.o]
[abcdoO.o]
remove_beginning
Note:
从 FreeMarker 2.3.21 开始,此内置功能可用。
从字符串的开头删除参数子字符串,或者如果原始字符串不是以参数子字符串开头的,则返回原始字符串。例如:
${"abcdef"?remove_beginning("abc")}
${"foobar"?remove_beginning("abc")}
will print:
def
foobar
remove_ending
Note:
从 FreeMarker 2.3.21 开始,此内置功能可用。
从字符串的结尾删除参数子字符串,或者如果原始字符串不以参数子字符串结尾,则返回原始字符串。例如:
${"abcdef"?remove_ending("def")}
${"foobar"?remove_ending("def")}
will print:
abc
foobar
rtf (deprecated)
Note:
2.3.24 中引入的auto-escaping mechanism不推荐使用此内置函数。通常,为了防止双重转义和混乱,在启用自动转义的地方使用此内置符号是parse-time error。为了帮助迁移,此内置插件无提示地绕过 RTF 标记输出值而不更改它们。
字符串为 RTF 文本(RTF 文本)。也就是说,所有字符串:
\
替换为\\
{
替换为\{
}
替换为\}
split
它用于将一个字符串沿着另一个字符串的出现拆分为一系列字符串。例如:
<#list "someMOOtestMOOtext"?split("MOO") as x>
- ${x}
</#list>
will print:
- some
- test
- text
请注意,假定所有出现的分隔符都在新项之前(带有"r"
标志的除外-稍后请参见),因此:
<#list "some,,test,text,"?split(",") as x>
- "${x}"
</#list>
will print:
- "some"
- ""
- "test"
- "text"
- ""
split
接受可选的flags parameter作为其第二个参数。 r
(正则表达式)标志存在历史故障;它将从结果列表的末尾删除空元素,因此在最后一个示例中使用?split(",", "r")
,输出中将缺少最后一个""
。
如果第一个参数为空字符串,则该字符串将被拆分为字符(因为 FreeMarker 2.3.28-较早的版本仅适用于r
标志)。
Note:
要检查字符串是否以某些内容结尾并附加其他内容,请使用sure_ends_with 内置。
starts_with
返回此字符串是否以指定的子字符串开头。例如"redirect"?starts_with("red")
返回布尔值true
。同样,"red"?starts_with("red")
将返回true
。
Note:
要检查字符串是否以某个东西开头,否则以开头,请使用sure_starts_with 内置。
字符串(与字符串值一起使用时)
不执行任何操作,仅按原样返回字符串。唯一的 exception 是,如果该值为多类型值(例如,它同时是字符串和序列),则结果值将只是一个简单的字符串,而不是多类型值。这可以用来防止多重 Importing 的伪像。
substring (deprecated)
Note:
从 FreeMarker 2.3.21 开始,此内建版本已被slicing expressions弃用,例如str[from..<toExclusive]
,str[from..]
和str[from..*maxLength]
。
如果正在处理 XML,则发出警告:由于切片表达式同时适用于序列和字符串,并且由于 XML 节点通常同时同时是序列和字符串,因此等效表达式为someXmlNode?string[from..<toExclusive]
和exp?string[from..]
,因为不使用?string
它将切片节点 Sequences 而不是节点的文本值。
Note:
方便的内置方法涵盖了一些字符串切片的典型用例:remove_beginning,remove_ending,keep_before,keep_after,keep_before_last,keep_after_last
剧情简介:exp?substring(from, toExclusive)
,也可以称为exp?substring(from)
字符串的子字符串。 from
是第一个字符的索引。它必须是一个至少为 0 且小于或等于toExclusive
的数字,否则错误将中止模板处理。 toExclusive
是子字符串的最后一个字符之后的字符位置的索引,换句话说,它比最后一个字符的索引大一个。它必须是一个至少为 0 且小于或等于字符串长度的数字,否则错误将中止模板处理。如果省略toExclusive
,则默认为字符串的长度。如果参数是不是整数的数字,则将仅使用数字的整数部分。
Example:
- ${'abc'?substring(0)}
- ${'abc'?substring(1)}
- ${'abc'?substring(2)}
- ${'abc'?substring(3)}
- ${'abc'?substring(0, 0)}
- ${'abc'?substring(0, 1)}
- ${'abc'?substring(0, 2)}
- ${'abc'?substring(0, 3)}
- ${'abc'?substring(0, 1)}
- ${'abc'?substring(1, 2)}
- ${'abc'?substring(2, 3)}
The output:
- abc
- bc
- c
-
-
- a
- ab
- abc
- a
- b
- c
trim
没有前导和尾随空格的字符串。例:
(${" green mouse "?trim})
The output:
(green mouse)
truncate, truncate_...
如果有必要将字符串的末尾保留为参数指定的长度,则将其截断,并附加一个终止符字符串(默认为[...]
)以指示该字符串已被截断。示例(假设默认的 FreeMarker 配置设置):
<#assign shortName='This is short'>
<#assign longName='This is a too long name'>
<#assign difficultName='This isoneveryverylongword'>
No truncation needed:
${shortName?truncate(16)}
Truncated at word boundary:
${longName?truncate(16)}
Truncated at "character boundary":
${difficultName?truncate(16)}
No truncation needed:
This is short
Truncated at word boundary:
This is a [...]
Truncated at "character boundary":
This isonev[...]
以上注意事项:
如果字符串的长度未超过指定的长度(在这种情况下为 16),则返回该字符串。
当字符串超过该长度时,将其末端剪断,以使其与添加的终止符字符串(此处为
[...]
)一起不超过 16.为了更好看,结果长度可能小于 16. (请参阅下文)。实际上,当所需长度比单独的终止符字符串短时,结果长度也可以大于参数长度,在这种情况下,终止符仍按原样返回。另外,默认算法以外的其他算法可能会选择返回更长的字符串,因为 length 参数原则上只是暗示所需的视觉长度。truncate
倾向于在单词边界处进行剪切,而不是在中间单词处进行剪切,但是,如果这样做的结果是比参数指定的长度的 75%短,则它会回切到中间单词处。在以上示例的最后一行中,“ This [...]”将太短(11 <16 * 75%),因此将其改为中间词。如果剪切发生在单词边界,则单词 end 和终止符字符串之间有一个空格,否则它们之间没有空格。仅将空格视为单词分隔符,而不将其用作标点符号,因此通常可以得出直观的结果。
调整截断规则
通过设置truncate_builtin_algorithm
配置设置,可以高度配置截断规则。这可以由程序员(而不是模板作者)完成,因此,有关更多详细信息和示例,请参阅Configurable.setTruncateBuiltinAlgorithm的 JavaDoc。
截断规则也可以在模板中受到较小程度的影响:
指定截断是否应发生在单词边界处:
truncate_w
将始终在单词边界处截断。例如,difficultName?truncate_w(16)
返回“ This [...]”,而不是“ This isonev [...]”(如先前示例所示)。truncate_c
会截断任何字符,而不仅限于字尾。例如,longName?truncate_c(16)
返回“ This is a t [...]”,而不是“ This is a [...]”(如前面的示例所示)。这倾向于使字符串的长度更接近于指定的长度,但仍不是确切的长度,因为它去除了终止符字符串之前的空白,并且如果我们刚好在单词的结尾之后,则重新添加了一个空格,等等。
指定终止符字符串(而不是依赖于其默认值):
truncate
和所有truncate_...
内置插件都具有附加的可选参数。之后,另一个可选参数可以指定终止符字符串的假定长度(否则将使用其实际长度)。如果您发现自己经常指定终止符字符串,则可以肯定应配置默认值(通过truncate_builtin_algorithm configuration
-参见前面)。例:
${longName?truncate(16, '...')}
${longName?truncate(16, '...', 1)}
This is a ...
This is a too ...
当终止符字符串以点(.
)或省略号(…
)开头时,默认算法将删除终止符所接触的点和椭圆,以防止结尾处有 3 个以上的点:
${'Foo bar.baaz'?truncate(11, '---')}
${'Foo bar.baaz'?truncate(11, '...')} (Not "Foo bar....")
${'Fo bar. baaz'?truncate(11, '...')} (Word separator space prevents touching)
Foo bar.---
Foo bar... (Not "Foo bar....")
Fo bar. ... (Word separator space prevents touching)
使用标记作为终止符字符串
每个内置的截断都有一个变体,其名称以_m
结尾(用于标记)。这些允许使用标记(如 HTML)作为终止符,如果您希望终止符的样式与截断文本的样式不同,则这很有用。默认情况下,标记终止符是<span class='truncateTerminator'>[…]</span>
(其中…
打印省略号字符),但是当然可以使用truncate_builtin_algorithm
配置设置更改它(请参见前面)。示例(请参阅前面示例中使用的变量):
${longName?truncate_m(16)}
${difficultName?truncate_w_m(16)}
${longName?truncate_c_m(16)}
This is a <span class='truncateTerminator'>[…]</span>
This <span class='truncateTerminator'>[…]</span>
This is a to<span class='truncateTerminator'>[…]</span>
上面请注意,截断内置项将终止符字符串视为仅 3 个字符长('['
,'…'
,']'
),因为终止符字符串内部仅计算 HTML/XML 标签和 Comments 之外的字符,并且它们也可以解释数字字符引用(但不解释其他实体引用)。 (当他们决定终止符以点或省略号开头时,也是如此;前面的标记/Comments 被跳过,等等.)
如果使用标记终止符(如上),则truncate..._m
内置返回值也将是标记,这意味着auto-escaping不会转义它。当然,截断的字符串本身的内容仍将自动转义:
<#ftl output_format='HTML'>
${'This is auto-escaped: <span>'}
${'This is auto-escaped: <span>, but not the terminator string'?truncate_m(41)}
This is auto-escaped: <span>
This is auto-escaped: <span>, but not <span class='truncateTerminator'>[…]</span>
uncap_first
与cap_first相反。字符串中第一个单词的字符串不大写。
upper_case
字符串的大写版本。例如"GrEeN MoUsE"
将是"GREEN MOUSE"
。
url
Note:
从 FreeMarker 2.3.1 开始可以使用此内置功能。它在 2.3 中不存在。
URL 转义后的字符串。这意味着所有非 US-ASCII 和保留的 URL 字符都将使用%XX
进行转义。例如:
<#assign x = 'a/b c'>
${x?url}
输出将是(假设用于转义的字符集是与 US-ASCII 兼容的字符集):
a%2Fb%20c
请注意,它会转义所有个保留的 URL 字符(/
,=
,&
等),因此此编码可用于编码查询参数值,例如:
<a href="foo.cgi?x=${x?url}&y=${y?url}">Click here...</a>
Note:
上面根本不需要 HTML 编码(?html
),因为 URL 转义无论如何都会转义所有保留的 HTML 字符。但是请注意:总是用属性引号引起来,并且总是用普通引号("
),而不用撇号('
),因为 URL 转义不会使撇号引起来。
要进行 URL 转义,必须选择charset并将其用于计算转义的部分(%XX
)。如果您是 HTML 页面的作者,但是您不太了解这一点,请不要担心:程序员应该配置 FreeMarker,以便默认情况下使用正确的字符集(程序员:请参见下文...)。如果您是技术性更高的用户,那么您可能想知道所使用的字符集是由url_escaping_charset
设置指定的,可以在模板执行时间中设置(或最好由程序员更早地设置)。例如:
<#--
This will use the charset specified by the programmers
before the template execution has started.
-->
<a href="foo.cgi?x=${x?url}">foo</a>
<#-- Use UTF-8 charset for URL escaping from now: -->
<#setting url_escaping_charset="UTF-8">
<#-- This will surely use UTF-8 charset -->
<a href="bar.cgi?x=${x?url}">bar</a>
此外,您可以为转义的单个 URL 显式指定一个字符集作为内置参数:
<a href="foo.cgi?x=${x?url('ISO-8895-2')}">foo</a>
如果内置的url
没有参数,则它将使用指定的字符集作为url_escaping_charset
设置的值。此设置应由包含 FreeMarker 的软件(例如 Web 应用程序框架)进行设置,因为默认情况下未设置(null
)。如果未设置,则 FreeMarker 会使用output_encoding
设置的值进行回退,该值也是默认情况下未设置的,因此这也是封闭软件的任务。如果也未设置output_encoding
设置,则无法执行内置的无参数url
,这将导致执行时间错误。当然,带有参数的url
内置参数始终有效。
可以使用setting
指令在模板中设置url_escaping_charset
,但这是一种不好的做法,至少在 true 的 MVC 应用程序中。不能使用setting
指令设置output_encoding
设置,因此这肯定是封闭软件的任务。您可能会找到有关此here...的更多信息
url_path
Note:
从 FreeMarker 2.3.21 开始,此内置功能可用。
与内置 URL相同,除了它不转义斜杠(/
)字符。这意味着用于将使用斜杠(而不是反斜杠!)的路径(例如来自 OS 或某些内容存储库的路径)转换为可以插入 URL 的路径。需要进行此转换的最常见原因是文件夹名称或文件名可能包含非 US-ASCII 字母(“国家”字符)。
Note:
就像内置 URL一样,必须在 FreeMarker 配置设置中设置所需的 URL 转义字符集(或作为后退,输出编码),否则内置错误。或者,您必须指定somePath?url_path('utf-8')
这样的字符集。
word_list
一个序列,该序列按出现在字符串中的 Sequences 包含字符串的所有单词。单词是连续的字符序列,包含除white-space之外的任何字符。例:
<#assign words = " a bcd, . 1-2-3"?word_list>
<#list words as word>[${word}]</#list>
will output:
[a][bcd,][.][1-2-3]
xhtml (deprecated)
Note:
2.3.24 中引入的auto-escaping mechanism不推荐使用此内置函数。通常,为了防止双重转义和混乱,在启用自动转义的地方使用此内置符号是parse-time error。为了帮助迁移,此内置插件无提示地绕过 HTML 标记输出值而不更改它们。
字符串为 XHTML 文本。也就是说,所有字符串:
<
替换为<
>
替换为>
&
替换为&
"
替换为"
'
替换为'
此内置和xml
内置之间的唯一区别是xhtml
内置将'
转换为'
而不是'
,因为某些较旧的浏览器不知道'
。
Warning!
插入属性值时,请始终将其引号,否则攻击者可能会利用它!这是错误的:<input name="user" value=${user?xhtml}/>
。这些很好:<input name="user" value="${user?xhtml}"/>
,<input name="user" value='${user?xhtml}'/>
。
xml (deprecated)
Note:
2.3.24 中引入的auto-escaping mechanism不推荐使用此内置函数。通常,为了防止双重转义和混乱,在启用自动转义的地方使用此内置符号是parse-time error。为了帮助迁移,此内置插件无提示地绕过 XML 和 HTML 标记输出值而不更改它们。
字符串为 XML 文本。也就是说,所有字符串:
<
替换为<
>
替换为>
&
替换为&
"
替换为"
'
替换为'
Warning!
插入属性值时,请始终引用该属性,否则攻击者可能会利用它!这是错误的:<input name="user" value=${user?xml}/>
。这些很好:<input name="user" value="${user?xml}"/>
,<input name="user" value='${user?xml}'/>
。
Common flags
许多内置字符串都接受可选的字符串参数,即所谓的“标志”。在此字符串中,每个字母都会影响内置行为的某个方面。例如,字母i
表示内置函数不应区分同一字母的大小写形式。标志字符串中字母的 Sequences 不重要。
这是字母(标志)的完整列表:
i
:不区分大小写:请勿区分同一字母的大小写。f
:仅第一位。也就是说,替换/查找/等。只有第一次出现。r
:要查找的子字符串是regular expression。 FreeMarker 使用在http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html处描述的正则表达式的变体(请注意,某些模式功能的存在取决于所使用的 Java 版本)。m
:用于正则表达式的多行模式。在多行模式下,表达式^
和$
分别在行终止符或字符串结尾之后或之前匹配。默认情况下,这些表达式仅在整个字符串的开头和结尾匹配。请注意,^
和$
与换行符本身不匹配。s
:为正则表达式启用全点模式(与 Perl 单行模式相同)。在全点模式下,表达式.
匹配任何字符,包括行终止符。默认情况下,此表达式与行终止符不匹配。c
:允许在正则表达式中包含空格和 Comments。
Example:
<#assign s = 'foo bAr baar'>
${s?replace('ba', 'XY')}
i: ${s?replace('ba', 'XY', 'i')}
if: ${s?replace('ba', 'XY', 'if')}
r: ${s?replace('ba*', 'XY', 'r')}
ri: ${s?replace('ba*', 'XY', 'ri')}
rif: ${s?replace('ba*', 'XY', 'rif')}
这输出:
foo bAr XYar
i: foo XYr XYar
if: foo XYr baar
r: foo XYAr XYr
ri: foo XYr XYr
rif: foo XYr baar
这是使用这些公共标志的内置表,并支持以下标志:
Built-in | i (忽略大小写) |
r (常规) |
m (多行模式) |
s (全点模式) |
c (空白和 Comments) |
f (仅第一个) |
---|---|---|---|---|---|---|
replace |
Yes | Yes | 仅适用于r |
仅适用于r |
仅适用于r |
Yes |
split |
Yes | Yes | 仅适用于r |
仅适用于r |
仅适用于r |
No |
matches |
Yes | Ignored | Yes | Yes | Yes | No |
keep_after |
Yes | Yes | Yes | Yes | Yes | Ignored |
keep_after_last |
Yes | Yes | Yes | Yes | Yes | Ignored |
keep_before |
Yes | Yes | Yes | Yes | Yes | Ignored |
keep_before_last |
Yes | Yes | Yes | Yes | Yes | Ignored |
ensure_starts_with |
Yes | Ignored | Yes | Yes | Yes | Ignored |