009_字符串内建函数
1. 內建函數就像FreeMarker在對象中添加的方法一樣。要防止和實際方法和其它子變量的命名沖突, 則不能使用點(.), 這里使用問號(?)來和父對象分隔開。
2. 為了簡潔, 如果方法沒有參數, 那么就可以忽略(), 比如: 想要獲取path的長度, 就可以寫作: path?length, 而不是path?length()。
3. 內建函數關鍵性的另外一個原因是FreeMarker不會暴露對象的Java API。盡管Java的String類有length()方法, 但在模板中卻是不可見的, 就不得不使用path?length來代替。這里的優點是模板不依賴下層Java對象的精確類型。
4. boolean
4.1. 字符串轉為布爾值。字符串必須是true或false, 或者必須是由boolean_format設置的特定格式。
4.2. 如果字符串不是適當的格式, 那么當訪問該內建函數時, 就會發成錯誤終止模板處理。
4.3. boolean_format的默認字符串是"true,false"。
4.4. FreeMarker還自帶了一個boolean_format是c的值。
4.5. boolean_format用戶還可以自定義, 使用逗號分割真和假的值。
5. cap_first
5.1. 字符串中的首單詞的首字母大寫。
6. uncap_first
6.1. 和cap_first相反。字符串中首單詞的首字母小寫。
7. capitalize
7.1. 字符串中所有單詞的首字母大寫。
8. upper_case
8.1. 字符串的大寫形式。
9. lower_case
9.1. 字符串的小寫形式。
10. contains
10.1. 如果函數中的參數指定的子串出現在源字符串中, 那么返回true。
11. starts_with
11.1. 字符串是否以指定的子字符串開頭, 返回布爾值。
12. ends_with
12.1. 字符串是否以指定的子字符串結尾, 返回布爾值。
13. ensure_starts_with
13.1. 如果字符串沒有以第一個參數指定的子串開頭, 那么就會將它加到字符串開頭, 否則返回原字符串。
13.2. 如果指定兩個參數, 那么第一個參數就被解釋成Java正則表達式, 如果它不匹配字符串的開頭, 那么第二個參數指定的字符串就會添加到字符串開頭。
13.3. 該方法也接受第三個標志位參數。"r"查找的子串是正則表達式。i比較是大小寫不敏感的。值得注意的一點是當不需要第一參數被解釋成正則表達式, 而只是普通文本, 但是又想讓比較是大小寫不敏感的, 那么此時就需要使用"i"作為第三個參數。
14. ensure_ends_with
14.1. 如果字符串沒有以第一個參數指定的子串結尾, 那么就會將它加到字符串后面, 否則返回原字符串。
15. index_of
15.1. 返回第一次字符串中出現子串時的索引位置。不要忘了第一個字符的索引是0。
15.2. 你可以使用第二個參數指定開始搜索的索引位置。
15.3. 第二個參數的數值沒有限制。如果它是負數, 那就和是0是相同效果了; 如果它比字符串的長度還大, 那么就和它是字符串長度那個數值是一個效果。小數會被切成整數。
16. last_index_of
16.1. 返回最后一次(最右邊)字符串中出現子串時的索引位置。它返回子串第一個(最左邊)字符所在位置的索引。
16.2. 可以使用第二個參數來指定開始搜索的索引。要注意第二個參數暗示了子串開始的最大索引。
16.3. 對第二個參數的數值沒有限制: 如果它是負數, 會始終返回-1;?如果它比字符串的長度還大, 那么就和它是字符串長度那個數值是一個效果。小數會被切成整數。
16.4. 如果第一個參數作為子串沒有在該字符串中出現時(如果你使用了第二個參數, 那么就從給定的序列開始), 那么就返回-1。
17. html/xhtml
17.1. 字符串按照html標記輸出。也就是說, 下面字符串將會被替代:
18. keep_before
18.1. 移除字符串的一部分, 該部分是從給定子串開始的部分。
18.2. 如果參數字符串沒有找到, 它會返回空串。如果參數是長度為0的字符串, 它會返回源字符串, 不會改變。
18.3. 該方法接受可選的標志位參數, 作為它的第二個參數。
19. keep_after
19.1. 移除字符串中的一部分內容, 該部分是給定子串第一次出現之前的部分。
19.2. 如果參數字符串沒有找到, 它會返回空串。如果參數是長度為0的字符串, 它會返回源字符串, 不會改變。
19.3. 該方法接受可選的標志位參數, 作為它的第二個參數。
20. keep_before_last
20.1. 和keep_before相同, 但是保留參數最后一次出現之前的部分, 而不是第一次出現之前。
21. keep_after_last
21.1. 和keep_after相同, 但是它會保留參數最后一次出現后的部分, 而不是第一次。
22. left_pad
22.1. 如果它僅僅用1個參數, 那么它將在字符串的開始插入空白, 直到整個串的長度達到參數指定的值。如果字符串的長度達到指定數值或者比指定的長度還長, 那么就什么都不做了。
22.2. 如果使用了兩個參數, 那么第一個參數表示的含義和你使用一個參數時的相同, 第二個參數指定用什么東西來代替空白字符。
22.3. 第二個參數也可以是個長度比1大的字符串。那么這個字符串會周期性的插入。
22.4. 第二個參數必須是個字符串值, 而且至少有一個字符。
23. right_pad
23.1. 它和left_pad 相同, 但是它從末尾開始插入字符而不是從開頭。
24. length
24.1. 字符串中字符的數量。
25. number
25.1. 字符串轉化為數字格式。這個數字必須是"計算機語言"格式。也就是說, 它必須是本地化獨立的形式, 小數的分隔符就是一個點, 沒有分組。
25.2. 此外, 它也識別科學記數法(比如 "1.23E6", "1.5e-8") 。
26. replace
26.1. 在源字符串中, 用另外一個字符串來替換原字符串中出現它的部分。它不處理詞的邊界。
26.2. 替換是從左向右執行的。比如: ${"aaaaa"?replace("aaa", "X")}, 將會輸出Xaa。
26.3. 如果第一個參數是空字符串, 那么所有的空字符串將會被替換, 比如: "foo"?replace("","|"), 就會得到 "|f|o|o|"。
26.4. replace 接受可選的 標志位參數, 作為它的第三參數。
27. remove_beginning
27.1. 從字符串的開頭移除參數中的子串, 如果它不以參數中的子串開頭, 那么就或者返回原字符串。
28. remove_ending
28.1. 從字符串的結尾移除參數中的子串, 如果它不以參數中的子串結尾, 那么就或者返回原字符串。
29. split
29.1. 它被用來根據另外一個字符串的出現將原字符串分割成字符串序列。
30. trim
30.1. 去掉字符串首尾的空格。
30. url
30.1. 在URL之后的字符串進行轉義。這意味著, 所有非US-ASCII的字符和保留的URL字符將會被%XX形式轉義。
30.2. 請注意, 它會轉義所有保留的URL字符(/, ?=, ?&, 等...), 所以可以被用來編碼查詢參數值。
30.3. 為了進行URL轉義, 必須要選擇字符集, 它被用來計算被轉義的部分(%XX)。
30.4. 如果內建函數url沒有參數, 那么它會使用由url_escaping_charset設置的字符集。這個設置應該被軟件設置, 包括FreeMarker(比如Web應用框架), 因為它默認不會被設置(null)。 如果它沒有被設置, 那么FreeMarker退回使用output_encoding的設置, 這個也會被默認設置, 所以它也是又軟件設置的。如果output_encoding也沒有被設置, 那么沒有參數的內建函數url 將不會被執行, 而且它會引起運行時錯誤。當然, 有參數的url函數將會執行。
30.5. 用setting指令在模板中設置url_escaping_charset是可能的。至少在真實的MVC應用中, 這是一個不好的實踐行為。output_encoding不能由setting指令來設置, 所以它應該是軟件的工作。
31. url_path
31.1. 它和url內建函數相同, 只是它不轉義斜杠(/)字符。這就是意味著用來轉義使用了斜杠(不是反斜杠!)的路徑(比如操作系統或一些內容倉庫的路徑), 轉義之后它們可以插入到URL中。需要該轉義的常用原因是文件夾名稱或文件名稱可能含有非US-ASCII字母("國家"標準符號)。
32. word_list
32.1. 包含字符串中所有單詞的序列, 順序為出現在字符串中的順序。單詞是不間斷的字符序列, 包含了任意字符, 但是沒有空白。
33. 通用標志
33.1. 很多字符串內建函數接受可選的字符串參數, 它們被稱為"標志"。在這個字符串中, 每個字母影響內建函數一個特定方面的行為。比如, 字母i說明內建函數不應該區別相同字母的小寫和大寫變化。標志字符串中的字母順序是不重要的。
33.2. 下面是字母(標志)的完整列表
33.2.1. i: 不區別相同字母的小寫和大寫變化。
33.2.2. f: 只是第一個。
33.2.3. r: 查找的子串是正則表達式。
33.2.4. m: 正則表達式的多行模式。在多行正則表達式^和$, 各自匹配行終止符或字符串結尾。
33.2.5. s: 開啟正則表達式的dot-all模式。在dot-all模式下, 表達式.匹配任意字符串, 包含行終止符。默認情況下, 該表達式不匹配行終止符。
33.2.6. c: 允許正則表達式中的空白和注釋。
33.3. 下表是支持使用這些通用標志的內建函數
34. 例子
34.1. 新建一個名為FMBuiltInsForStrings的動態Web工程, 同時添加相關jar包。
34.2. 編寫FMFactory.java
package com.fm.util;import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import freemarker.template.Configuration; import freemarker.template.TemplateExceptionHandler;public class FMFactory {private final static FMFactory instance = new FMFactory();private FMFactory() {}public static FMFactory getInstance() {return instance;}private Map<String, Configuration> map = new ConcurrentHashMap<String, Configuration>();// 創建單個Configuration實例public synchronized Configuration getCfg(Object servletContext, String path) {if(null != map.get(path)) {return map.get(path);}Configuration cfg = new Configuration(Configuration.VERSION_2_3_22);cfg.setServletContextForTemplateLoading(servletContext, path);// 默認編碼cfg.setDefaultEncoding("utf-8");// url轉義編碼cfg.setURLEscapingCharset("utf-8");// 輸出編碼cfg.setOutputEncoding("utf-8");// 設置可以進行布爾值格式化的值cfg.setBooleanFormat("開,關");cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);map.put(path, cfg);return cfg;}}34.3. 編寫BuiltInsForStrings.java
package com.fm.action;import java.io.IOException; import java.io.OutputStreamWriter; import java.io.Writer; import java.sql.Date; import java.sql.Time; import java.sql.Timestamp; import java.util.HashMap; import java.util.Map; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.fm.util.FMFactory; import freemarker.template.Configuration; import freemarker.template.Template; import freemarker.template.TemplateException;public class BuiltInsForStrings extends HttpServlet {private static final long serialVersionUID = 1L;@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {Configuration cfg = FMFactory.getInstance().getCfg(req.getServletContext(), "/WEB-INF/templates");Template template = cfg.getTemplate("builtinsforstrings.html");Map<String, Object> root = new HashMap<String, Object>();root.put("date", new Date(0));root.put("time", new Time(0));root.put("datetime", new Timestamp(0));Writer out = new OutputStreamWriter(resp.getOutputStream());try {template.process(root, out);} catch (TemplateException e) {e.printStackTrace();}}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req, resp);} }34.4. 修改web.xml
34.5. 在/WEB-INF/templates下編寫builtinsforstrings.html
<!DOCTYPE html> <html><head><meta charset="UTF-8" /><title>字符串內建函數</title></head><body><h2>字符串轉為布爾值</h2><#assign bln = "true" /><#if bln?boolean>字符串"true"轉布爾值成功。</#if><#assign bln = "開" /><#if bln?boolean>字符串"開"轉布爾值成功。</#if><h2>字符串中的首單詞的首字母大寫</h2>${"chinese china"?cap_first}<h2>字符串中首單詞的首字母小寫</h2>${"China And Chinese"?uncap_first}<h2>字符串中所有單詞的首字母大寫</h2>${"china chinese"?capitalize}<h2>字符串的大寫形式</h2>${"China And Chinese"?upper_case}<h2>字符串的小寫形式</h2>${"China And Chinese"?lower_case}<h2>包含字符串</h2><#if "我們是中國人"?contains("中國人")>我們是中國人包含<b>中國人</b>。</#if><h2>字符串轉換成日期值, 時間或日期-時間值</h2>${"1970-1-1"?date}${"8:00:00"?time}${"1970-1-1 8:00:00"?datetime}<h2>字符串是否以指定的子字符串開頭</h2><#if "我們是中國人"?starts_with("我們")>我們是中國人以<b>我們</b>開頭。</#if><h2>字符串是否以指定的子字符串結尾</h2><#if "我們是中國人"?ends_with("中國人")>我們是中國人以<b>中國人</b>結尾。</#if><h2>以指定字符串開頭</h2>${"WEB-INF/templates"?ensure_starts_with("/")}<br />${"localhost:8080/"?ensure_starts_with("https?://", "http://")}<br /><#-- r查找的子串是 正則表達式。i比較是大小寫不敏感的。-->${"HTTPS://localhost:8080/"?ensure_starts_with("https?://", "http://", "ri")}<h2>以指定字符串結尾</h2>${"WEB-INF/templates"?ensure_ends_with("/")}<h2>返回第一次字符串中出現子串時的索引位置</h2>"我們是中國人我們是中國人", 第一個"們"的位置: ${"我們是中國人我們是中國人"?index_of("們")}<br />"我們是中國人我們是中國人", 從第-3的位置起, 第一個"們"的位置: ${"我們是中國人我們是中國人"?index_of("們", -3)}<br />"我們是中國人我們是中國人", 從第20的位置起, 第一個"們"的位置: ${"我們是中國人我們是中國人"?index_of("們", 20)}<br />"我們是中國人我們是中國人", 從第7的位置起, 第一個"們"的位置: ${"我們是中國人我們是中國人"?index_of("們", 7)}<h2>返回最后一次(最右邊)字符串中出現子串時的索引位置</h2>"abcabc", 最后一次"ab"出現的位置: ${"abcabc"?last_index_of("ab")}<br />"abcabc", 從-2的位置算, 最后一次"ab"出現的位置: ${"abcabc"?last_index_of("ab", -2)}<br />"abcabc", 從-1的位置算, 最后一次"ab"出現的位置: ${"abcabc"?last_index_of("ab", -1)}<br />"abcabc", 從0的位置算, 最后一次"ab"出現的位置: ${"abcabc"?last_index_of("ab", 0)}<br />"abcabc", 從1的位置算, 最后一次"ab"出現的位置: ${"abcabc"?last_index_of("ab", 1)}<br />"abcabc", 從2的位置算, 最后一次"ab"出現的位置: ${"abcabc"?last_index_of("ab", 2)}<br />"abcabc", 從3的位置算, 最后一次"ab"出現的位置: ${"abcabc"?last_index_of("ab", 3)}<br />"abcabc", 從4的位置算, 最后一次"ab"出現的位置: ${"abcabc"?last_index_of("ab", 4)}<br />"abcabc", 從5的位置算, 最后一次"ab"出現的位置: ${"abcabc"?last_index_of("ab", 5)}<br />"abcabc", 從6的位置算, 最后一次"ab"出現的位置: ${"abcabc"?last_index_of("ab", 6)}<br />"abcabc", 從7的位置算, 最后一次"ab"出現的位置: ${"abcabc"?last_index_of("ab", 7)}<h2>字符串按照html標記輸出</h2>${"<b>\"true\" & 'false'</b>"?html}<h2>移除字符串中的一部分內容</h2><#-- \s匹配空格 -->${"abcdef"?keep_before("de")}<br />${"foo : bar"?keep_before(r"\s*:\s*", "r")}<br />${"abcdefgh"?keep_after("de")}<br />${"foo : bar"?keep_after(r"\s*:\s*", "r")}<br />${"foo.bar.txt"?keep_before_last(".")}<br />${"foo.bar.txt"?keep_after_last(".")}<h2>開始位置插入足量空白</h2><pre>[${"abc"?left_pad(6)}]</pre><pre>[${"abc"?left_pad(3)}]</pre>[${"abc"?left_pad(6, "-")}]<br />[${"abc"?left_pad(6, "-*&")}]<h2>結束位置插入足量空白</h2><pre>[${"abc"?right_pad(6)}]</pre><pre>[${"abc"?right_pad(3)}]</pre>[${"abc"?right_pad(6, "-")}]<br />[${"abc"?right_pad(6, "-*&")}]<h2>字符串中字符的數量</h2>"我們都是中國人。"字符數量: ${"我們都是中國人。"?length}<h2>字符串轉化為數字格式</h2>"123"轉化為數字格式: ${"123"?number}<br />"1.23E6"轉化為數字格式: ${"1.23E6"?number}<br />"1.5e-8"轉化為數字格式: ${"1.5e-8"?number}<h2>替換字符串</h2>${"我們都是中國人。我們都是中國人。"?replace("們都", "")}<br />${"我們都是中國人。"?replace("", "|")}<br />${"aaaaa"?replace("aaa", "X")}<br />${"aaaaaAAAAA"?replace("aaa", "X", "i")}<br /><h2>從字符串的開頭移除參數中的子串</h2>${"abcdef"?remove_beginning("abc")}<br />${"defabc"?remove_beginning("abc")}<h2>從字符串的結尾移除參數中的子串</h2>${"defabc"?remove_ending("def")}<br />${"abcdef"?remove_ending("def")}<h2>分割字符串</h2><#list "some,,test,text,"?split(",") as x>"${x}"<br /></#list><h2>去掉字符串首尾的空格</h2>[${" 你好哇 "?trim}]<h2>在URL之后的字符串進行轉義</h2>${"a/b c"?url("ISO-8859-1")}<br />${"<>'"?url("UTF-8")}<br /><#-- 設置url轉義編碼, 最好不要在這里設置, 在程序里設置。 --><#setting url_escaping_charset="UTF-8">${"a/b c"?url}<br />${"<>'"?url}<h2>url_path不轉義斜杠</h2>${"/<>/'/"?url_path("UTF-8")}<h2>包含字符串中所有單詞的序列</h2><#assign words = " a bcd, . 1-2-3"?word_list /><#list words as word>${word}<#sep><br /></#sep></#list></body> </html>34.6. 運行項目
總結
以上是生活随笔為你收集整理的009_字符串内建函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 007_表达式
- 下一篇: 010_数字内建函数