前言
FreeMarker replace 內建函數支援正則表達式替換,語法為 str?replace(regex, replacement, flags)。本文詳細講解三個參數、六大標誌位、實戰示例與常見坑點。
語法簽名
${str?replace(pattern, replacement, flags)}
| 參數 | 說明 |
pattern | 正則表達式(Java Pattern 語法) |
replacement | 替換字符串,支持 $1 等組引用 |
flags | 可選標誌位字符串(如 "ri") |
六大標誌位詳解
| 標誌 | 全稱 | 作用 | 備註 |
i | CASE_INSENSITIVE | 忽略大小寫匹配 | 常用 |
r | REGEX | 啟用正則模式(預設為字面量替換) | 必須,否則 pattern 視為普通字符串 |
m | MULTILINE | ^ $ 匹配行首尾 | 配合 r 使用 |
s | DOTALL | . 匹配換行符 | 配合 r 使用 |
c | COMMENTS | 允許正則中空白和註釋 | 配合 r 使用 |
f | FIRST_ONLY | 僅替換第一次匹配 | 獨立使用 |
實戰示例
<#assign s = "foo bAr baar">
${s?replace("ba", "XY")} // 字面量替換:foo bAr XYar
${s?replace("ba", "XY", "i")} // 忽略大小寫:foo XYr XYar
${s?replace("ba", "XY", "if")} // 忽略大小寫+首次:foo XYr baar
${s?replace("ba*", "XY", "r")} // 正則:ba* 匹配 b, ba, baa... → foo XYAr XYr
${s?replace("ba*", "XY", "ri")} // 正則+忽略大小寫:foo XYr XYr
${s?replace("ba*", "XY", "rif")}// 正則+忽略大小寫+首次:foo XYr baar
進階示例:移除「數字+積分」前綴
<#assign str = "2積分兌換30元優惠券">
${str?replace("\\b\\d+積分", "", "r")}
// 輸出:兌換30元優惠券
// \b 詞邊界,\d+ 數字,"積分" 字面量
常見坑點避坑指南
- 忘記
r 標誌:預設字面量替換,正則元字符不生效。
- 轉義雙重陷阱:FTL 字符串與正則雙層轉義,
"\\\\d" → 正則見 \\d → 匹配數字。
- 組引用語法:替換字符串用
$1(非 \1),FreeMarker 直接傳給 Matcher.appendReplacement。
- 性能:大模板中重複調用同一正則,建議在 Java 端預編譯
Pattern 後傳入自定義方法處理。
總結速查表
| 需求 | flags 組合 | 示例 |
| 正則替換所有 | "r" | s?replace("\\d+", "#", "r") |
| 正則忽略大小寫 | "ri" | s?replace("error", "OK", "ri") |
| 正則僅首次 | "rf" | s?replace("foo", "bar", "rf") |
| 多行模式 ^$ | "rm" | s?replace("^TODO:", "", "rm") |
| 單行模式 .匹配換行 | "rs" | s?replace(".*", "X", "rs") |
掌握 r 必須、i/f/m/s/c 組合,即可駕馭 FreeMarker 90% 的文本替換場景。