FreeMarker 字串內建函數完整參考:常用操作、格式化、轉義與正則擴展
FreeMarker 提供豐富的字串內建函數,涵蓋大小寫轉換、子字串擷取、正則比對、編碼轉義、日期/數值解析等。本文整理官方文檔核心函數,附語法、參數、範例與常見旗標說明,供模板開發快速查閱。
一、大小寫與首字母控制
| 函數 | 說明 | 範例輸出 |
upper_case | 全轉大寫 | "GrEeN"?upper_case → "GREEN" |
lower_case | 全轉小寫 | "GrEeN"?lower_case → "green" |
cap_first | 首個單字首字母大寫 | "green mouse"?cap_first → "Green mouse" |
uncap_first | 首個單字首字母小寫 | "Green Mouse"?uncap_first → "green Mouse" |
capitalize | 所有單字首字母大寫 | "green mouse"?capitalize → "Green Mouse" |
單字定義:參考 word_list,連續非空白字元視為一個單字。
二、修剪與移除
| 函數 | 說明 | 範例 |
trim | 移除首尾空白 | " hi "?trim → "hi" |
chop_linebreak | 移除結尾單一換行 | "hi\n"?chop_linebreak → "hi" |
remove_beginning("prefix") | 移除開頭指定前綴 | "abcdef"?remove_beginning("abc") → "def" |
remove_ending("suffix") | 移除結尾指定後綴 | "abcdef"?remove_ending("def") → "abc" |
ensure_starts_with("prefix") | 確保開頭有前綴,無則加上 | "foo"?ensure_starts_with("/") → "/foo" |
ensure_ends_with("suffix") | 確保結尾有後綴,無則加上 | "foo"?ensure_ends_with("/") → "foo/" |
ensure_starts_with 支援正則模式(第二參數為替換字串、第三參數旗標)。
三、子字串擷取與分割
| 函數 | 說明 | 範例 |
substring(from, toExclusive?) | 已棄用,改用切片語法 str[from..<to] | "abc"[0..<2] → "ab" |
keep_before("sub") | 保留首次出現 sub 之前 | "abcdef"?keep_before("de") → "abc" |
keep_after("sub") | 保留首次出現 sub 之後 | "abcdef"?keep_after("de") → "f" |
keep_before_last("sub") | 保留最後一次出現 sub 之前 | "foo.bar.txt"?keep_before_last(".") → "foo.bar" |
keep_after_last("sub") | 保留最後一次出現 sub 之後 | "foo.bar.txt"?keep_after_last(".") → "txt" |
split("sep") | 按分隔字串分割為序列 | "a,b,c"?split(",") → ["a","b","c"] |
word_list | 拆解為單字序列 | " a bcd ."?word_list → ["a","bcd","."] |
keep_before/after 等支援旗標(第二參數),可啟用正則、忽略大小寫等。
四、查找與比對
| 函數 | 說明 | 回傳值 |
contains("sub") | 是否包含子字串 | boolean |
starts_with("prefix") | 是否以 prefix 開頭 | boolean |
ends_with("suffix") | 是否以 suffix 結尾 | boolean |
index_of("sub", fromIndex?) | 首次出現索引(0-based),找不到 -1 | int |
last_index_of("sub", fromIndex?) | 最後一次出現索引,找不到 -1 | int |
matches("regex") | 整字串是否符合正則 | 多型值:boolean + 序列(匹配子串) |
groups | 搭配 matches 取得捕獲群組 | 序列 |
<#assign res = "foo bar fyo"?matches("f.?o")>
<#if res>Matches<#else>No match#if>
<#list res as m>${m}#list> // 輸出 foo, fyo
<#assign g = "John Doe"?matches(r"(\w+) (\w+)")>
${g?groups[1]} → John, ${g?groups[2]} → Doe
五、替換與填充
| 函數 | 說明 | 範例 |
replace("target", "repl", flags?) | 替換所有 target(支援旗標 r 正則、f 首次、i 忽略大小寫) | "car car"?replace("car","bus") → "bus bus" |
left_pad(len, padStr?) | 左側填充至指定長度(預設空白) | "a"?left_pad(5,"-") → "----a" |
right_pad(len, padStr?) | 右側填充 | "a"?right_pad(5,"-") → "a----" |
六、編碼轉義(輸出安全)
| 函數 | 用途 | 轉義規則 | 狀態 |
html | HTML 屬性/內文 | < > & " ' → < > & " ' | 已棄用(2.3.24+ 自動轉義) |
xhtml | XHTML | 同 html,' → ' | 已棄用 |
xml | XML | ' → ' | 已棄用 |
js_string | JavaScript 字串字面值 | " ' \ / < > 控制字元 → \xXX/\uXXXX | 正常 |
json_string | JSON 字串字面值 | 同 js_string,但 ' 不轉義、> → \u003E | 正常 |
j_string | Java 字串字面值 | 控制字元 → \uXXXX | 正常 |
url | URL 參數值編碼 | 非 US-ASCII 與保留字 → %XX | 正常 |
url_path | URL 路徑段編碼 | 同 url 但不轉義 / | 正常 |
rtf | RTF 文件 | \ { } → \\ \{ \} | 已棄用 |
esc | 當前輸出格式轉義並標記為標記輸出 | 依 output_format | 2.3.24+ |
no_esc | 標記為標記輸出,跳過自動轉義 | 原樣輸出 | 2.3.24+ |
最佳實踐:啟用 <#ftl output_format="HTML" auto_esc=true>,框架自動處理轉義,僅在需輸出原始 HTML/JS 片段時使用 ?no_esc。
七、型別轉換與解析
| 函數 | 說明 | 格式設定 |
number | 字串轉數值 | 電腦格式(點號分隔、無分組),支援科學記號、NaN、INF |
boolean | 字串轉布林 | "true"/"false" 或 boolean_format 設定 |
date/time/datetime | 字串轉日期/時間/日期時間 | 依 date_format/time_format/datetime_format;可指定 ?date.xs、?date("MM/dd/yyyy")、?date.@custom |
<#assign d = "2024-01-15"?date.xs> // ISO 日期
<#assign dt = "2024-01-15T14:30"?datetime.iso> // ISO 日期時間
<#assign n = "1,234.56"?number> // 錯誤:含逗號。需先 replace(",", "")
八、常用旗標對照表
多函數共用旗標字串(字母順序無關):
| 旗標 | 含義 | 適用函數示例 |
i | 忽略大小寫 | replace, split, matches, keep_before, starts_with 等 |
f | 僅首次出現 | replace |
r | 正則模式 | replace, split, matches, keep_before, ensure_starts_with 等 |
m | 多行模式(^ $ 匹配行首尾) | 配合 r 使用 |
s | 單行模式(. 匹配換行) | 配合 r 使用 |
c | 允許正則中的空白與註解 | 配合 r 使用 |
${"foo bAr"?replace("ba", "XY", "if")} // 忽略大小寫、僅首次 → "foo XYr"
${"a,b,c"?split(",", "r")} // 正則分割(移除尾部空元素)
九、長度與布林轉字串
length:字元數("abc"?length → 3)。
string:無操作返回字串本身,可剝離多型值標記。
十、遷移建議(2.3.24+ 自動轉義時代)
- 移除手動
?html/?xhtml/?xml,依賴 auto_esc。
- 需輸出信任 HTML 片段時,使用
?no_esc(而非 ?html 疊加)。
- 子字串操作統一改用切片語法
str[from..<to]、str[from..]、str[from..*len]。
- XML 節點同時為字串與序列時,切片前加
?string:node?string[0..<10]。