解析器函數是一個MediaWiki擴充,由mw:Extension:ParserFunctions提供。
ParserFunctions擴充提供11個額外的解析器函數以補充MediaWiki原生的「魔術字」。(有可能會組態到額外的解析器函數以支持執行;這些字串函數已在其他文件頁面記載。)
此擴充提供的所有解析器函數均採用以下形式:
{{#函数名: 参数1 | 参数2 | 参数3... }}
各函數名都對大小寫不敏感。陳述式中的空格、換行等空白字元將被省略。
#expr
類型 | 運算符號 |
---|---|
分組(括弧) | ( )
|
數字 | 1234.5 e (2.718) pi (3.142)
|
二進制運算子 e 一元 + ,-
| |
一元 | not ceil trunc floor abs exp ln sin cos tan acos asin atan
|
二進制 | ^
|
* / div mod
| |
+ -
| |
取整 | round
|
邏輯 | = != <> > < >= <=
|
and
| |
or
|
這個函數計算數學表達式並返回計算值。
在nsp=0中可以透過mw.ext.ParserFunctions.expr
來使用此函數。
{{#expr: 表达式 }}
右表依優先級列出了支持的運算子。運算結果的精度和格式受執行wiki伺服器作業系統和站點語言的數字格式影響可能存在差異。
使用布林代數時,0表示false
,其他任何非0數值(無論正負)均表示true
:
{{#expr: 1 and -1 }}
→ 1{{#expr: 1 and 0 }}
→ 0{{#expr: 1 or -1 }}
→ 1{{#expr: -1 or 0 }}
→ 1{{#expr: 0 or 0 }}
→ 0
空表達式返回空值,無效的表達式返回錯誤資訊,使用#iferror
函數檢查錯誤:
{{#expr: }}
→{{#expr: 1+ }}
→ 表達式錯誤:缺少+的運算元。{{#expr: 1 = }}
→ 表達式錯誤:缺少=的運算元。{{#expr: 1 foo 2 }}
→ 表達式錯誤:無法辨識詞語「foo」。
置於數字前或數字後的加減號是有意義的,會被視為正負號而不會報錯:
{{#expr: +1 }}
→ 1{{#expr: -1 }}
→ -1{{#expr: + 1 }}
→ 1{{#expr: - 1 }}
→ -1
注意:使用魔術字輸出數值時,首先要將其格式化以去除逗號,獲得純數字。例如:{{NUMBEROFUSERS}}輸出1,587,而期望的輸出值是1587,使用{{formatnum:{{NUMBEROFUSERS}}|R}}
便可以實現。對於某些語言,格式化數字尤為重要。例如孟加拉語中,{{NUMBEROFUSERS}}的輸出結果是৩০,০৬১。
{{#expr:{{NUMBEROFUSERS}}+100}}
→ 表達式錯誤:無法辨識標點符號「,」。{{#expr:{{formatnum:{{NUMBEROFUSERS}}|R}}+100}}
→ 1687
mod
會對第二參數的某些值給出錯誤的結果:
{{#expr: 123 mod (2^64-1)}}
→ 除以零。 (輸出一個空字串;應該是123)
如果你想要进行基于日期时间的计算(如检测当前日期时间是否超过指定日期时间),首先用{{#time: xNU }}将日期时间转换为距1970年1月1日的秒数,再对秒数进行加减运算。
→ 如果你想要進行基於日期時間的計算(如檢測當前日期時間是否超過指定日期時間),首先用1714065900將日期時間轉換為距1970年1月1日的秒數,再對秒數進行加減運算。
四捨五入
將左邊的數字四捨五入為1/10的冪的倍數,指數等於右邊給出的數字的截斷值(truncated value)。
向上、向下取整分別使用ceil
或floor
。
案例 | 結果 | 捨入方式 |
---|---|---|
{{#expr: 1/3 round 5 }} |
0.33333 | 最終的數字小於5,所以沒有明顯的取整發生 (0.333333… → 0.33333) |
{{#expr: 1/6 round 5 }} |
0.16667 | 最終的數字大於5,所以被向上取整 (0.166666… → 0.16667) |
{{#expr: 8.99999/9 round 5 }} |
1 | 同理,最後一位數因後一位而加1,進而引起了前面的進位 (0.999998… → 1.00000 → 1) |
{{#expr: 1234.5678 round -2 }} |
1200 | 捨入至最近的整百數,負值在小數點左邊。 |
{{#expr: 1234.5678 round 2 }} |
1234.57 | 捨入至最近的整1/100數,因為正值會捨入至小數點右邊。 |
{{#expr: 1234.5678 round 2.3 }} |
1234.57 | 捨入指數的小數點在捨入結果中不起作用 |
{{#expr: trunc 1234.5678 }} |
1234 | 小數部分被全部捨棄(截斷) |
四捨五入至最近的整數 | ||
{{#expr: 1/3 round 0 }} |
0 | 向下取整至0 |
{{#expr: 1/2 round 0 }} |
1 | 向上取整至1 |
{{#expr: 3/4 round 0 }} |
1 | 向上取整至1 |
{{#expr: -1/3 round 0 }} |
-0 | 向上取整至0 |
{{#expr: -1/2 round 0 }} |
-1 | 向下取整至-1 |
{{#expr: -3/4 round 0 }} |
-1 | 向下取整至-1 |
使用ceil和floor向上或向下取整 | ||
{{#expr: ceil(1/3) }} |
1 | 向上取整至1 |
{{#expr: floor(1/3) }} |
0 | 向下取整至0 |
{{#expr: ceil(-1/3) }} |
-0 | 向上取整至0 |
{{#expr: floor(-1/3) }} |
-1 | 向下取整至-1 |
{{#expr: ceil 1/3 }} |
0.33333333333333 | 沒有取整,因為1本來就是整數 注意會被解析為(ceil 1)/3,而不是你想像中的ceil(1/3) |
字串
表達式函數只用於僅含有數字和運算符號的表達式,而字母字串和其它符號不在此列。若需要比較字串,可以用#ifeq替代。
{{#expr: "a" = "a" }}
→ 表達式錯誤:無法辨識標點符號「"」。{{#expr: a = a }}
→ 表達式錯誤:無法辨識詞語「a」。{{#ifeq: a | a | 1 | 0 }}
→ 1
#if
這個函數判斷一個字串是否為空。只包含空格的字串被視為空字串。
{{#if: 测试字符串 | 测试字符串非空时的取值 | 测试字符串为空或仅包含空白字符时的取值 }}
{{#if: 参数1 | 参数2 | 参数3 }}
這個函數首先判斷參數1是否為空。如果參數1不為空,則輸出參數2。如果參數1為空或只包含空白內容(空格、換行等),則輸出參數3。
{{#if: | yes | no}}
→ no{{#if: string | yes | no}}
→ yes{{#if: | yes | no}}
→ no{{#if:
→ no
| yes | no}}
字串內容會被處理為純文字,因此不會計算數學表達式(參見#ifexpr):
{{#if: 1==2 | yes | no }}
→ yes{{#if: 0 | yes | no }}
→ yes
最後一個參數(false)可以忽略:
{{#if: foo | yes }}
→ yes{{#if: | yes }}
→{{#if: foo | | no}}
→
該函數可巢狀。為了做到這一點,巢狀內層的#if函數需要按規則完整填寫所有參數以符合#if的參數形式。一般至多可巢狀7層,該數也可能為wiki自身限制和記憶體限制而有變動。
{{#if: 测试字符串 | 字符串非空时的值 | {{#if: 测试字符串 | 字符串非空时的值 | 字符串为空(或只有空格)的值 }} }}
你可以在#if
條件句中以字串變數代替測試字串。在這裏,你需要在變數名的後面加上|
(分隔符)以正確引用字串。
(因此如果參數沒有值,則計算結果為一個空字串而非"{{{1}}}
"。)
{{#if:{{{1|}}}|你在變數1裏面輸入了文字|變數1裏面沒有文字}}
參見mw:Help:Parser functions in templates以了解更多關於解析器函數中變數的相關例子。
#ifeq
這個函數判斷兩個輸入字串是否相同,並根據結果輸出兩個字串的其中一個。
如果需要更多的比較和輸出字串,請考慮使用#switch
。
{{#ifeq: string 1 | string 2 | value if identical | value if different }}
如果兩個字串均為數字,則函數會進行數值的比較:
{{#ifeq: 01 | 1 | equal | not equal}}
→ equal{{#ifeq: 0 | -0 | equal | not equal}}
→ equal{{#ifeq: 1e3 | 1000 | equal | not equal}}
→ equal{{#ifeq: {{#expr:10^3}} | 1000 | equal | not equal}}
→ equal
否則,函數會進行文字的比較(大小寫敏感):
{{#ifeq: foo | bar | equal | not equal}}
→ not equal{{#ifeq: foo | Foo | equal | not equal}}
→ not equal{{#ifeq: "01" | "1" | equal | not equal}}
→ not equal (對比上面沒有引號的例子){{#ifeq: 10^3 | 1000 | equal | not equal}}
→ not equal (對比上面帶有#expr
的例子,會先回傳一個有效的整數)
作為例子,考慮一個已存在的模板Template:Timer
,該模板利用解析器來選擇兩個標準時間,short和long。
它以參數作為第一個輸入來比較字串「short」–這沒有約定順序,但是如果參數在第一個則更容易理解。
模板代碼定義為:
{{#ifeq: {{{1|}}} | short | 20 | 40 }}
會產生如下結果:
{{timer|short}}
→ 20{{timer|20}}
→ 40{{timer}}
→ 40
{{#ifeq: <nowiki>foo</nowiki> | <nowiki>foo</nowiki> | equal | not equal}}
→ not equal{{#ifeq: <math>foo</math> | <math>foo</math> | equal | not equal}}
→ not equal{{#ifeq: {{#tag:math|foo}} | {{#tag:math|foo}} | equal | not equal}}
→ not equal{{#ifeq: [[foo]] | [[foo]] | equal | not equal}}
→ equal
為了解決這個問題,將這個魔術字應用到兩個參數上:
{{#ifeq: {{FULLPAGENAME: L'Aquila}} | {{FULLPAGENAME}} | equal | not equal}}
→ equal
#iferror
這個函數接收一個輸入字串,返回兩個結果中的一個。如果輸入字串包含一個由其他解析器函數(比如#expr
、#time
和#rel2abs
)、模板錯誤(比如模板迴圈和模板遞歸)或其他解析器「軟錯誤」生成的class="error"
的HTML對象,那麼視為真。
{{#iferror: test string | value if error | value if correct }}
待返回字串參數可以省略。若省略"correct"
(正確)字串參數,則在"test string"
(測試字串)不出錯的情況下函數將返回被測字串本身。若省略"error"
(錯誤)字串參數,則函數將在被測字串出錯時返回空字串:
{{#iferror: {{#expr: 1 + 2 }} | error | correct }}
→ correct{{#iferror: {{#expr: 1 + X }} | error | correct }}
→ error{{#iferror: {{#expr: 1 + 2 }} | error }}
→ 3{{#iferror: {{#expr: 1 + X }} | error }}
→ error{{#iferror: {{#expr: 1 + 2 }} }}
→ 3{{#iferror: {{#expr: 1 + X }} }}
→ {{#iferror: {{#expr: . }} | error | correct }}
→ correct{{#iferror: <strong class="error">a</strong> | error | correct }}
→ error
Some errors may cause a tracking category to be added, using {{#iferror:}}
will not suppress the addition of the category.
#ifexpr
此函數會判斷數學表達式並根據其布林值結果返回對應的字串:
{{#ifexpr: expression | value if true | value if false }}
這裏"expression"
輸入串將原封不動的作為上面#expr
的參數進行呼叫,且表達式運算子是通用的,返回值也將作為布林表達式進行處理。
輸入表達式為空時將視為false
:
{{#ifexpr: | yes | no}}
→ no
如上面所提,0將視為false
,非零值將視為true
,因此這個函數與下面的僅用#ifeq
和#expr
的表述等價:
{{#ifeq: {{#expr: expression }} | 0 | value if false | value if true }}
除了下面這種情況:所輸入表達式為空或者是一個錯誤表達式(空字串會返回一條錯誤資訊,而它不等於0,所以在後者我們會得到"value if true"
)。
{{#ifexpr: = | yes | no }}
→ 表達式錯誤:預期外的=運算子。
相對的
{{#ifeq: {{#expr: = }} | 0 | no | yes }}
→ yes
兩個返回值都可以省略,當合適的對應分支被省略時,函數不輸出:
{{#ifexpr: 1 > 0 | yes }}
→ yes{{#ifexpr: 1 < 0 | yes }}
→{{#ifexpr: 0 = 0 | yes }}
→ yes{{#ifexpr: 1 > 0 | | no}}
→{{#ifexpr: 1 < 0 | | no}}
→ no{{#ifexpr: 1 > 0 }}
→
Boolean operators of equality or inequality operators are supported.
{{#ifexpr: 0 = 0 or 1 = 0 | yes}}
→ yes{{#ifexpr: 0 = 0 and 1 = 0 | | no}}
→ no{{#ifexpr: 2 > 0 or 1 < 0 | yes}}
→ yes{{#ifexpr: 2 > 0 and 1 > 0 | yes | no}}
→ yes
#ifexpr
進行數字比較的結果不總是與#ifeq
和#switch
的結果一致。 後面兩種比較相對於#ifexpr
而言更加精確,因而未必返回相同結果。
考慮比較下面兩個僅有最後一位數不同的數:
{{#ifeq: 12345678901234567 | 12345678901234568 | equal | not equal}}
→ not equal{{#switch: 12345678901234567 | 12345678901234568 = equal | not equal}}
→ not equal
因為#ifeq
和#switch
使用的PHP會比較兩個整數類型的數,會正確返回預期結果。
然而用#ifexpr
比較相同的兩個數時:
{{#ifexpr: 12345678901234567 = 12345678901234568 | equal | not equal}}
→ equal
對於不同的數字,結果實際上是不正確的。
造成#ifexpr
出錯行為的原因是MediaWiki將兩個數依字面表達理解成了浮點數,而對於像這樣的大數,轉換為浮點數由於精度誤差會儲存為一樣的數值,導致出錯。
#ifexist
這個函數將一組字串作為輸入,並翻譯成頁面標題,然後根據在本地wiki上是否存在該頁面而返回對應的值。
{{#ifexist: page title | value if exists | value if doesn't exist }}
只要頁面存在就會判定為true
(真值),即便那個頁面看上去是空白的(比如像是分類連結或者是魔術字解釋頁之類的卻不包含任何可視內容的頁面),或者是重新導向頁面,或者它就是空白頁。若且唯若頁面是紅色連結時判定為false
(假值),包括那些曾經存在卻被刪除的頁面。
{{#ifexist: Help:解析器函数 | exists | doesn't exist }}
→ exists{{#ifexist: XXHelp:解析器函数XX | exists | doesn't exist }}
→ doesn't exist
函數在系統訊息被自訂時返回true
,對特殊頁面的判定則取決於本地軟件自身。
{{#ifexist: Special:监视列表 | exists | doesn't exist }}
→ exists{{#ifexist: Special:用户查核 | exists | doesn't exist }}
→ exists (因為nsp=0擴充已經安裝於此wiki){{#ifexist: MediaWiki:Copyright | exists | doesn't exist }}
→ exists (因為MediaWiki:Copyright已自訂)
如果一個頁面使用了#ifexist:
來檢查目標頁面,則這個檢查頁面將出現在被檢查頁面的Special:連入頁面里。所以如果本頁面(Help:解析器函數)使用了代碼 {{#ifexist:Foo}}
,那麼Special:連入頁面/Foo將列出Help:解析器函數。
若wiki有其在使用的對應的共用媒體庫,#ifexist:
就可用於檢查一個檔案是否在媒體庫中,而不僅僅只是在wiki本體上檢查:
{{#ifexist: File:Example.png | exists | doesn't exist }}
→ exists{{#ifexist: Image:Example.png | exists | doesn't exist }}
→ exists{{#ifexist: Media:Example.png | exists | doesn't exist }}
→ exists
如果檔案有一個已建立的對應的本地描述頁面,上面的結果將全部是exists。
#ifexist:
不會對跨站連結起作用。
ifexist 限制
#ifexist:
被視為「高開銷(expensive)解析器函數」,每個頁面呼叫這類函數的次數(包括包含於嵌入式模板的函數)存在一個限制。
當達到該限制時,更多的#ifexist:
函數,無論其目標頁面是否存在,只會自動返回錯誤值false,且該頁面會被分類到Category:有過多高開銷解析器函數呼叫的頁面中。
追蹤分類的名稱可能因您的wiki內容的語言而異。
一些情況下,在css中使用選擇器a.new
(以選出連結到不存在的頁面的連結)或者是a:not(.new)
(以選出已存在頁面的連結),是可以達到模仿ifexist的效果的。
另外,$wgExpensiveParserFunctionLimit
可以調整對高開銷解析器函數數量的限制,如果有需要,也可以增加頁面LocalSettings.php中的限制值。
ifexisit和需要的頁面
一個不存在的頁面被#ifexist檢測後會被計數在待建立頁面中。
#rel2abs
這個函數將檔案的相對路徑轉換為絕對路徑。
{{#rel2abs: path }}
{{#rel2abs: path | base path }}
在輸入項path
中,可以使用以下類型的句法:
.
→ 本級路徑..
→ 回到上一級/foo
→ 向下一級進入子目錄/foo
若base path
沒有指定,將預設的填入函數所在頁面的絕對路徑:
{{#rel2abs: /quok | Help:Foo/bar/baz }}
→ Help:Foo/bar/baz/quok{{#rel2abs: ./quok | Help:Foo/bar/baz }}
→ Help:Foo/bar/baz/quok{{#rel2abs: ../quok | Help:Foo/bar/baz }}
→ Help:Foo/bar/quok{{#rel2abs: ../. | Help:Foo/bar/baz }}
→ Help:Foo/bar
無效語法,如/.
或/./
,將被忽略。
由於不允許超過兩個連續的句號,因此可以使用諸如此類的序列來分隔連續的陳述式:
{{#rel2abs: ../quok/. | Help:Foo/bar/baz }}
→ Help:Foo/bar/quok{{#rel2abs: ../../quok | Help:Foo/bar/baz }}
→ Help:Foo/quok{{#rel2abs: ../../../quok | Help:Foo/bar/baz }}
→ quok{{#rel2abs: ../../../../quok | Help:Foo/bar/baz }}
→ 錯誤:路徑深度無效:「Help:Foo/bar/baz/../../../../quok」(試圖存取根節點之上的節點)。
For a similar group of functions see also Help:Magic words#URL data. Built-in parser functions include: 'localurl:', 'fullurl:', 'anchorencode:' etc.
#switch
該函數將一個輸入值同若干個測試用例(test cases)做比較,如果找到匹配,返回有關聯的字串。
{{#switch: comparison string | case = result | case = result | ... | case = result | default result }}
例如:
{{#switch: baz | foo = Foo | baz = Baz | Bar }}
→ Baz{{#switch: foo | foo = Foo | baz = Baz | Bar }}
→ Foo{{#switch: zzz | foo = Foo | baz = Baz | Bar }}
→ Bar
含有部分嵌入包含標記的#switch會影響到能讓不熟悉模板代碼的編輯者檢視和編輯可組態元素的設定檔。
預設
如果comparison string
不能與任何case
匹配,則返回default result
:
{{#switch: test | foo = Foo | baz = Baz | Bar }}
→ Bar
在這種語法中,預設返回值必須是函數的最後一個參數,而且不能包含原始等號(不帶{{}}
的等號)。
否則,就會解析為樣例比較,無匹配的樣例時不顯示文字。
這是因為預設值沒有定義(是空的)。
如果有樣例匹配,則返回關聯的字串。
{{#switch: test | Bar | foo = Foo | baz = Baz }}
→{{#switch: test | foo = Foo | baz = Baz | B=ar }}
→{{#switch: test | test = Foo | baz = Baz | B=ar }}
→ Foo
你也可以將case
字串設為#default
從而清楚地聲明預設值。
{{#switch: comparison string | case = result | case = result | ... | case = result | #default = default result }}
這種方式聲明的預設結果可以放在函數的任何地方:
{{#switch: test | foo = Foo | #default = Bar | baz = Baz }}
→ Bar
如果"default"
參數被省略,且沒有找到匹配,則不返回結果:
{{#switch: test | foo = Foo | baz = Baz }}
→
分組結果
該函數允許有「跌落」值,多個"case"
字串返回相同的"result"
字串,從而減少重複。
{{#switch: comparison string | case1 = result1 | case2 | case3 | case4 = result234 | case5 = result5 | case6 | case7 = result67 | #default = default result }}
在本例中,第二、三、四個分支都會返回"result234"
,第六和第七個分支都會返回"result67"
。
上述案例中,最後一個參數中的「#default =
」可以省略。
帶有參數使用
該函數允許將參數用作測試字串。
在本例中,不必將管道符放在參數名稱後面,因為你不太可能需要選擇字串「{{{parameter name}}}
」作為樣例。
((如果沒有管道符,且參數不存在或沒有值,則參數就會顯示為這樣。)
參見Help:Parser functions in templates。)
{{#switch: {{{1}}} | foo = Foo | baz = Baz | Bar }}
上面的例子中,如果{{{1}}}
等於foo
,函數返回Foo
。
如果等於baz
,函數返回Baz
。
如果參數是空的或者不存在,函數返回Bar
。
上面的這些中,也可以將樣例組合起來以返回單個結果。
{{#switch: {{{1}}} | foo | zoo | roo = Foo | baz = Baz | Bar }}
如果{{{1}}}
等於foo
、zoo
或roo
,函數返回Foo
。
如果等於baz
,函數返回Baz
。
如果參數是空的或者不存在,函數返回Bar
。
而且,如果你希望在測試參數不能匹配任何樣例時不返回任何內容,可以省略預設結果。
{{#switch: {{{1}}} | foo = Foo | bar = Bar }}
在本例中,如果{{{1}}}
存在且等於foo
或bar
,則分別返回Foo
或Bar
,否則不返回任何內容。
這樣做相當於將預設值聲明為空。
{{#switch: {{{1}}} | foo | zoo | roo = Foo | baz = Baz | }}
如果由於某些原因需要將樣例設置為{{{parameter name}}}
,則函數在參數不存在或沒有值的情況下返回該樣例的結果。
參數需要存在且擁有不同於字串「{{{parameter name}}}
」的值以返回函數的預設結果。
- (若
{{{1}}}
不存在或者是空的):{{#switch: {{{1}}} | {{{1}}} = Foo | baz = Baz | Bar }}
→ Foo
- (若
{{{1}}}
的值為test
):{{#switch: {{{1}}} | {{{1}}} = Foo | baz = Baz | Bar }}
→ Bar
- (若
{{{1}}}
的值為「{{{1}}}
」):{{#switch: {{{1}}} | {{{1}}} = Foo | baz = Baz | Bar }}
→ Foo
在這樣的例子中,你需要給參數添加管道符({{{1|}}}
)。
比較行為
如同#ifeq
那樣,若被比較字串和測試用例字串都是數字,那麼按照數值進行比較;反之若存在一個非純數字串,都會按照字串比較規則進行:
{{#switch: 0 + 1 | 1 = one | 2 = two | three}}
→ three{{#switch: {{#expr: 0 + 1}} | 1 = one | 2 = two | three}}
→ one
{{#switch: a | a = A | b = B | C}}
→ A{{#switch: A | a = A | b = B | C}}
→ C
case
字串可以是空的:
{{#switch: | = Nothing | foo = Foo | Something }}
→ Nothing
只要找到一個匹配,後面的case
都會忽略:
{{#switch: b | f = Foo | b = Bar | b = Baz | }}
→ Bar
#switch
和#ifeq
的數值比較結果未必一致(參見上面#ifeq
部分):
{{#switch: 12345678901234567 | 12345678901234568 = A | B}}
→ B{{#ifexpr: 12345678901234567 = 12345678901234568 | A | B}}
→ A
原始等號
「case」字串不能包含原始等號。如果需要在比較串中加入等號,可以使用僅包含一個等號的模板模板連結:{{=}}來代替=
,或者是用HTML標識碼=
來代替。
例如:
您輸入的 | 您輸出的 |
---|---|
{{#switch: 1=2
| 1=2 = raw
| 1<nowiki>=</nowiki>2 = nowiki
| 1{{=}}2 = template
| default
}}
|
template |
{{#switch: 1=2
| 1=2 = html
| default
}}
|
html |
替換#ifeq
#switch
可以用於減少擴充深度。
例如:
{{#switch:{{{1}}} |condition1=branch1 |condition2=branch2 |condition3=branch3 |branch4}}
等效於
{{#ifeq:{{{1}}}|condition1 |branch1 |{{#ifeq:{{{1}}}|condition2 |branch2 |{{#ifeq:{{{1}}}|condition3 |branch3 |branch4}}}}}}
也就是線性的深度迭代判斷:
{{#ifeq:{{{1}}}|condition1
|<!--then-->branch1
|<!--else-->{{#ifeq:{{{1}}}|condition2
|<!--then-->branch2
|<!--else-->{{#ifeq:{{{1}}}|condition3
|<!--then-->branch3
|<!--else-->branch4}}}}}}
另一方面,對於巢狀在兩個分支中的if(以縮排形式呈現,兩側都縮排),替換成switch可能很複雜/不切實際,從而形成對稱樹:
{{#ifeq:{{{1}}}|condition1
|<!--then-->branch1t{{
#ifeq:{{{1}}}|condition2
|<!--then-->branch1t2t{{#ifeq:{{{1}}}|condition4|<!--then-->branch1t2t4t|<!--else-->branch1t2t4e}}
|<!--else-->branch1t2e{{#ifeq:{{{1}}}|condition5|<!--then-->branch1t2e5t|<!--else-->branch1t2e5e}}
}}
|<!--else-->branch1e{{#ifeq:{{{1}}}|condition3
|<!--then-->branch1e3t{{#ifeq:{{{1}}}|condition6|branch1e3t6t|branch1e3t6e}}
|<!--else-->branch1e3e{{
#ifeq:{{{1}}}|condition7
|branch1e3e7t
|branch1e3e7t
}}
}}
}}
#time
代碼 | 描述 | 當前輸出 (重新整理此頁面的快取以更新) |
---|---|---|
年 | ||
Y
|
4位元數年。 | 2024 |
y
|
2位數年。 | 24 |
L
|
如果是閏年則為1,否則為0。 | 1 |
o
|
指定周的ISO-8601年。[note 1] | 2024[note 2] |
月 | ||
n
|
月指數,非零填充。 | 4 |
m
|
月指數,零填充。 | 04 |
M
|
月名的縮寫,使用網站語言。 | 4月 |
F
|
使用網站語言的完整月名。 | 4月 |
xg
|
不同於主格形式,以所有格形式返回月份名的全稱。這個代碼適用大多數的斯拉夫語言,比如波蘭語、俄語、白俄羅斯語、捷克語、斯洛伐克語、斯洛文尼亞語、烏克蘭語等。 | 波蘭語:{{#time:F Y|June 2010|pl}} → czerwiec 2010(主格) {{#time:d xg Y|20 June 2010|pl}} → 20 czerwca 2010(所有格) |
一年或一個月內的第幾天 | ||
j
|
月內的第幾天,沒有字首零。 | 25 |
d
|
月內的第幾天,用字首零填滿兩位。 | 25 |
z
|
年內的第幾天(一月一日視為第0天)。 要獲得ISO日期值請在此數基礎上加1。 |
115 |
周,以及周內的第幾天 | ||
W
|
ISO 8601周數,有字首零。 | 17 |
N
|
ISO 8601 一周中的某天(星期一為1, 星期日為7)。 | 4 |
w
|
一周內的某天(星期日為0,星期六為6)。 | 4 |
D
|
星期幾的簡寫。很少國際化。 | 四 |
l
|
星期幾的全稱。很少國際化。 | 星期四 |
小時 | ||
a
|
上午(00:00:00 → 11:59:59)返回「am」, 下午(12:00:00 → 23:59:59)返回「pm」。 | pm |
A
|
上面的a 項的大寫版本。
|
PM |
g
|
十二小時制的小時數(無字首零)。 | 5 |
h
|
十二小時制的小時(有字首零)。 | 05 |
G
|
二十四小時制的小時(無字首零)。 | 17 |
H
|
二十四小時制的小時(有字首零)。 | 17 |
分鐘和秒鐘 | ||
i
|
一小時內已過去的分鐘數(有字首零)。 | 25 |
s
|
一分鐘內已過去的秒數(有字首零)。 | 00 |
U
|
Unix時間。 自1970年1月1日00:00:00 GMT的秒數。 | 1714065900 |
時區 | ||
e
|
時區識別碼。 | UTC |
I
|
是否使用夏令時。 | 0 |
O
|
與格林尼治時間(GMT)的差值 | +0000 |
P
|
與格林威治時間(GMT)的差異,帶冒號 | +00:00 |
T
|
時區縮寫。 | UTC |
Z
|
時區偏移(秒)。 | 0 |
雜項 | ||
t
|
本月日數。 | 30 |
c
|
ISO 8601格式化日期,與Y-m-d"T"H:i:s+00:00 等效。
|
2024-04-25T17:25:00+00:00 |
r
|
RFC 5332規範化的日期。與D, j M Y H:i:s +0000 等價,但周名和月名可能不是國際化表述。
|
Thu, 25 Apr 2024 17:25:00 +0000 |
非公曆(格里曆)曆法 | ||
伊斯蘭教曆法 | ||
xmj
|
月內一日。 | 16 |
xmF
|
月的全名。 | 閃瓦魯月 |
xmn
|
月索引。 | 10 |
xmY
|
全年。 | 1445 |
伊朗曆法(Jalaly) | ||
xit
|
月內日數。 | 31 |
xiz
|
年內一日。 | 36 |
xij
|
月內一日。 | 6 |
xiF
|
月的全名。 | Ordibehesht |
xin
|
月索引。 | 2 |
xiY
|
全年。 | 1403 |
xiy
|
2位數年。 | 03 |
希伯來曆法 | ||
xjj
|
月內一日。 | 17 |
xjF
|
月的全名。 | 尼散月 |
xjt
|
月內日數。 | 30 |
xjx
|
月份名稱的所有格形式。 | Nisan |
xjn
|
月數。 | 7 |
xjY
|
全年。 | 5784 |
泰歷 | ||
xkY
|
泰太陽曆中的年份. 1941年前後,本條目可能與依泰歷的真實計算方式出的年份有變化. |
2567 |
民國曆/主體歷 | ||
xoY
|
全年。 | Y |
日本曆法 | ||
xtY
|
全年。 | 令和6 |
標記 | ||
xn
|
以ASCII原始數字表示的數字代碼。 | 在印地語中,{{#time:H, xnH}} 產生०६, 06。
|
xN
|
類似於xn ,但是作為一個toggled flag,會持續到字串的末尾或者字串中xN 下一次出現。
| |
xr
|
將下一個數字格式化為羅馬數字。僅適用於10000以內的數字 (MediaWiki 1.20之前的版本為3000以內) |
{{#time:xrY}} → MMXXIV
|
xh
|
將下一個數字格式化為希伯來數字。 | {{#time:xhY}} → ב'כ"ד
|
該解析器函數接收一個(公曆的)日期或者時間,並根據給定的語法將其格式化。可以指定日期/時間對象,預設則為魔術字Help:魔術字#Date and time的當前值——也就是說,頁面最後被彩現為HTML時的時間。
{{#time: format string }}
{{#time: format string | date/time object }}
{{#time: format string | date/time object | language code }}
{{#time: format string | date/time object | language code | local }}
右表列舉了支持的格式化代碼。任何不被辨識的格式化字串都不會被修改,這同樣適用於空白字元(系統不使用空白字元來解釋代碼)。格式化字串內有兩種方法來跳脫字元:
- 反斜槓後跟隨一個格式化字串會被解釋為單個原始的字元
- 用英文雙引號括起來的字元視為原始字元,引號將被移除。
此外,xx
會被解釋為單個原始的x。
由于格式化代碼列表會持續發展(支持新日曆,或支持以不同方式計算和格式化的新日期欄位),您應該跳脫所有需要傳入而保持不變的文字字元(不僅僅是格式化代碼當前使用的ASCII字母)。
不幸的是,目前,ASCII單引號仍未被視為當前已經受支持的ASCII雙引號(可標記文字文字)和反斜槓(在許多語言使用的字串常數中也必須跳脫,包括JSON、C、C++、PHP、JavaScript、Lua)的簡單替代方法(例如,雙引號在其他用途中是強制性的,例如JSON、C、C++等語言中的字串值的定界)。 因此,您仍然無法在不使用反斜槓跳脫的情況下嵌入任何文字雙引號(或者也可以使用其他彎引號、角形引號或方引號)。
{{#time: Y-m-d }}
→ 2024-04-25{{#time: [[Y]] m d }}
→ 2024 04 25{{#time: [[Y (year)]] }}
→ 2024 (24UTCpmThu, 25 Apr 2024 17:25:00 +0000){{#time: [[Y "(year)"]] }}
→ 2024 (year){{#time: i's" }}
→ 25'00"
date/time object
可以是任何PHP strtotime()函數接受的格式。
絕對(如20 December 2000
)、相對(如+20 hours
)和混合時間(如30 July +1 year
)格式均是可以的。
{{#time: r|now}}
→ Thu, 25 Apr 2024 17:25:01 +0000{{#time: r|+2 hours}}
→ Thu, 25 Apr 2024 19:25:01 +0000{{#time: r|now + 2 hours}}
→ Thu, 25 Apr 2024 19:25:01 +0000{{#time: r|20 December 2000}}
→ Wed, 20 Dec 2000 00:00:00 +0000{{#time: r|December 20, 2000}}
→ Wed, 20 Dec 2000 00:00:00 +0000{{#time: r|2000-12-20}}
→ Wed, 20 Dec 2000 00:00:00 +0000{{#time: r|2000 December 20}}
→ 錯誤:時間無效。
ISO 639-3(?)中的language code
允許字串顯示為指定語言。
{{#time:d F Y|1988-02-28|nl}}
→ 28 februari 1988{{#time:l|now|uk}}
→ четвер{{#time:d xg Y|20 June 2010|pl}}
→ 20 czerwca 2010
local
參數指定date/time object是指本地時區還是UTC時間。
這是一個布林參數,其值是透過轉換(casting)參數值來確定的(有關如何將字串轉換為布林值的詳細資訊,請參閱官方PHP文件)。
$wgLocaltimezone
設為UTC
,則當local
設為true
或false
時輸出無區別。參考下面的詳細範例:
{{#time: Y F d H:i:s|now|it|0}}
→ 2024 aprile 25 17:25:01{{#time: Y F d H:i:s|now|it|1}}
→ 2024 aprile 26 01:25:01{{#time: Y F d H:i:s|+2 hours||0}}
→ 2024 4月 25 19:25:01{{#time: Y F d H:i:s|+2 hours||1}}
→ 2024 4月 26 03:25:01
{{#time:c|2019-05-16T17:05:43+02:00|it}}
→ 2019-05-16T15:05:43+00:00{{#time:c|2019-05-16T17:05:43+02:00|it|0}}
→ 2019-05-16T15:05:43+00:00{{#time:c|2019-05-16T17:05:43+02:00|it|true}}
→ 2019-05-16T23:05:43+08:00
如果你已經計算了Unix時間戳,你可以透過添加@
符號字首來在日期計算中使用。
{{#time: U | now }}
→ 1714065901{{#time: r | @1714065900 }}
→ Thu, 25 Apr 2024 17:25:00 +0000
@
前綴,結果通常會出錯或是未預期的數值:
{{#time: r | 1970-01-01 00:16:39 }}
→ Thu, 01 Jan 1970 00:16:39 +0000{{#time: U | 1970-01-01 00:16:39 }}
→ 999{{#time: r | @999 }}
→ Thu, 01 Jan 1970 00:16:39 +0000 (正確){{#time: r | 999 }}
→ 錯誤:時間無效。 (不支援的年份格式){{#time: r | 1970-01-01 00:16:40 }}
→ Thu, 01 Jan 1970 00:16:40 +0000{{#time: U | 1970-01-01 00:16:40 }}
→ 1000{{#time: r | @1000 }}
→ Thu, 01 Jan 1970 00:16:40 +0000 (正確){{#time: r | 1000 }}
→ Fri, 25 Apr 1000 00:00:00 +0000 (被解讀為某年的當前月份和日期){{#time: r | 1970-01-01 02:46:39 }}
→ Thu, 01 Jan 1970 02:46:39 +0000{{#time: U | 1970-01-01 02:46:39 }}
→ 9999{{#time: r | @9999 }}
→ Thu, 01 Jan 1970 02:46:39 +0000 (正確){{#time: r | 9999 }}
→ Sun, 25 Apr 9999 00:00:00 +0000 (被解讀為某年的當前月份和日期){{#time: r | 1970-01-01 02:46:40 }}
→ Thu, 01 Jan 1970 02:46:40 +0000{{#time: U | 1970-01-01 02:46:40 }}
→ 10000{{#time: r | @10000 }}
→ Thu, 01 Jan 1970 02:46:40 +0000 (正確){{#time: r | 10000 }}
→ 錯誤:時間無效。 (不支援的年分格式)
{{#time: d F Y | 29 Feb 0100 }}
→ 01 3月 0100
(正確,沒有閏年),但是{{#time: r | 29 Feb 0100 }}
→ Mon, 01 Mar 0100 00:00:00 +0000 (錯誤,即使100也被解讀為2000,因為那是閏年){{#time: d F Y | 15 April 10000 }}
→ 錯誤:時間無效。{{#time: r | 10000-4-15 }}
→ Sat, 15 Apr 2000 10:00:00 +0000
年份數字0-99解釋為2000-2069和1970-1999,除非添加字首0以寫成四位數格式:
{{#time: d F Y | 1 Jan 6 }}
→ 01 1月 2006{{#time: d F Y | 1 Jan 06 }}
→ 01 1月 2006{{#time: d F Y | 1 Jan 006 }}
→ 01 1月 2006{{#time: d F Y | 1 Jan 0006 }}
→ 01 1月 0006 (4-digit format)
可以指定完整的或部分絕對的日期;函數會使用「當前」值「填充」日期中未被指定的部分。
{{#time: Y | January 1 }}
→ 2024
{{#time: Y m d H:i:s | June }}
→ 2024 06 25 00:00:00 給予這一天的開始,而不是當前月份中的日期和當前年份。{{#time: Y m d H:i:s | 2003 }}
→ 2003 04 25 00:00:00 給予這一天的開始,而不是這一年的當前日期。
填充日期有特例:
{{#time: Y m d H:i:s | June 2003 }}
→ 2003 06 01 00:00:00 給予這一天的開始和這個月的開始。
4位元數字總是被解讀為年分,而不是小時和分鐘:
{{#time: Y m d H:i:s | 1959 }}
→ 1959 04 25 00:00:00
6位數字儘量被解讀為小時、分鐘、秒,不然會被解讀為錯誤(而不是年份和月份):
{{#time: Y m d H:i:s | 195909 }}
→ 2024 04 25 19:59:09 輸入被視為時間而不是年+月代碼。{{#time: Y m d H:i:s | 196009 }}
→ 錯誤:時間無效。 雖然19:60:09不是有效時間,但196009不被解讀為1960年9月。
該函數執行一定數量的日期算數:
{{#time: d F Y | January 0 2008 }}
→ 31 12月 2007{{#time: d F | January 32 }}
→ 錯誤:時間無效。{{#time: d F | February 29 2008 }}
→ 29 2月{{#time: d F | February 29 2007 }}
→ 01 3月{{#time:Y-F|now -1 months}}
→ 2024-3月
#time
調用的格式字串的總長度限制為6000個字元。
時區問題
#time解析器函數有個bug(尤其是PHP DateTime),不允許傳入非整數的相對時區偏移。這個問題不適用於使用基於小時的時區,例如EDT。例如:
{{#time:g:i A | -4 hours }}
→ 1:25 PM
但是,印度(India)是UTC +5.5個小時的時間偏移,因此使用時區不會正常地計算相對時區偏移。因此:
{{#time:g:i A | +5.5 hours }}
→ 5:25 PM
要解決這個問題,可將時間簡單轉換為分鐘或者秒,像這樣:
{{#time:g:i A | +330 minutes }}
→ 10:55 PM{{#time:g:i A | +19800 seconds }}
→ 10:55 PM
(Tim Starling,該函數的開發者,提供了該解決方案的準確語法。)
#timel
該函數等價於{{#time: ... }}
,其中local
參數設置為true
,因此總是使用wiki的本地時間($wgLocaltimezone中設置的)。
該函數的語法為:
{{#timel: format string }}
{{#timel: format string | date/time object }}
{{#timel: format string | date/time object | language code }}
$wgLocaltimezone
設為UTC
,則當local
設為true
或false
時輸出無區別。例如,參考以下範例:
{{#time:c|now|it}}
→ 2024-04-25T17:25:01+00:00{{#time:c|now|it|0}}
→ 2024-04-25T17:25:01+00:00{{#time:c|now|it|1}}
→ 2024-04-26T01:25:01+08:00{{#timel:c|now|it}}
→ 2024-04-26T01:25:01+08:00
U
Unix時間。自1970年1月1日 00:00:00(GMT)以來的秒數。Z
時區偏移(秒)。{{#time: U}}
→ 1714065900{{#timel: U}}
→ 1714065900{{#time: Z}}
→ 0{{#timel: Z}}
→ 28800
#titleparts
此函數將頁面標題根據斜槓劃分成多個分段,然後輸出返回這些分段中的部分。
{{#titleparts: 頁面名稱 | 需要返回的分段數量 | 要返回的第一個分段 }}
如果沒有指定要返回的分段數量參數,則預設為「0」,會從要返回的第一個分段(包含)開始返回所有分段。如果要返回的第一個分段參數沒有指定或者為「0」,則預設為「1」。
{{#titleparts: Talk:Foo/bar/baz/quok }}
→ Talk:Foo/bar/baz/quok{{#titleparts: Talk:Foo/bar/baz/quok | 1 }}
→ Talk:Foo See also {{ROOTPAGENAME}}.{{#titleparts: Talk:Foo/bar/baz/quok | 2 }}
→ Talk:Foo/bar{{#titleparts: Talk:Foo/bar/baz/quok | 2 | 2 }}
→ bar/baz{{#titleparts: Talk:Foo/bar/baz/quok | | 2 }}
→ bar/baz/quok{{#titleparts: Talk:Foo/bar/baz/quok | | 5 }}
→
兩個值都接受負值。要返回的分段數量參數的負值會從字串的最後開始「剝離」分段。要返回的第一個分段參數的負值解釋為「從這一分段開始,從右邊開始計數」:
{{#titleparts: Talk:Foo/bar/baz/quok | -1 }}
→ Talk:Foo/bar/baz 從字串的末尾剝離一段 參見{{BASEPAGENAME}}。{{#titleparts: Talk:Foo/bar/baz/quok | -4 }}
→ 從字串的末尾剝離所有4段{{#titleparts: Talk:Foo/bar/baz/quok | -5 }}
→ 從字串的末尾剝離5段(多於已存在的){{#titleparts: Talk:Foo/bar/baz/quok | | -1 }}
→ quok 返回最後一段。 參見{{SUBPAGENAME}}。{{#titleparts: Talk:Foo/bar/baz/quok | -1 | 2 }}
→ bar/baz 從字串的末尾剝離一段,然後返回第二段及以後的段{{#titleparts: Talk:Foo/bar/baz/quok | -1 | -2 }}
→ baz 從倒數第二個元素開始複製;從字串的末尾剝離一段
處理前,頁面名稱參數是HTML解碼的:如果包含一些標準的HTML字元實體,將被轉換為純字元(內部使用UTF-8編碼,也就是與使用解析器函數的MediaWiki源頁面中的編碼相同)。
- 例如,頁面名稱中出現了
"
、"
、"
的地方,都會替換為"
。 - 不會執行從HTML到純文字的其他轉換,因此即使HTML標籤在頁面標題中無效,在此初始步驟中也會保持不變。
{{PAGENAME}}
和類似)會返回用多餘的HTML編碼的字串,即使其自身的輸入參數不是HTML編碼的:
titleparts解析器函數可以用作一個解決辦法,以轉換返回的字串,因此可以被其他的一些解析器函數正確處理,如果這些解析器函數參數中也會接收頁面名稱,比如{{PAGESINCAT:}}
(但對於HTML編碼的字串仍然不能正確處理)。
例如,如果當前頁面是Category:Côte-d'Or,那麼:
{{#ifeq: {{FULLPAGENAME}} | Category:Côte-d'Or | 1 | 0 }}
、{{#ifeq: {{FULLPAGENAME}} | Category:Côte-d'Or | 1 | 0 }}
都會返回1
;(#ifeq解析器函數不會對輸入參數進行HTML解碼)。{{#switch: {{FULLPAGENAME}} | Category:Côte-d'Or = 1 | #default = 0 }}
、{{#switch: {{FULLPAGENAME}} | Category:Côte-d'Or = 1 | #default = 0 }}
都會返回1
;(#switch解析器函數不會對輸入參數進行HTML解碼)。{{#ifexist: {{FULLPAGENAME}} | 1 | 0 }}
、{{#ifexist: Category:Côte-d'Or | 1 | 0 }}
甚至{{#ifexist: Category:Côte-d'Or | 1 | 0 }}
都會返回1
,如果這個分類頁面存在(#ifexpr解析器函數不會對輸入參數進行HTML解碼);{{PAGESINCAT: Côte-d'Or }}
返回非零數,如果該分類包含頁面或子分類,但是:{{PAGESINCAT: {{CURRENTPAGENAME}} }}
可能會無條件地返回0,就像:{{PAGESINCAT: {{PAGENAME:Category:Côte-d'Or}} }}
{{PAGESINCAT: {{PAGENAME:Category:Côte-d'Or}} }}
這種非預料行為的原因是,對於目前版本的MediaWiki,有兩個警告(caveats):
{{FULLPAGENAME}}
,或者甚至{{FULLPAGENAME:Côte-d'Or}}
可能會返回實際HTML編碼的字串Category:Côte-d'Or
而不是預期中的Category:Côte-d'Or
;{{PAGESINCAT: Côte-d'Or }}
無條件地返回0(PAGESINCAT魔術字不對輸入參數進行任何的HTML解碼)。
使用titleparts的簡單解決方法(如果上述兩個警告在MediaWiki的更高版本中修復了,也會繼續生效):
{{PAGESINCAT: {{#titleparts: {{CURRENTPAGENAME}} }} }}
{{PAGESINCAT: {{#titleparts: {{PAGENAME:Category:Côte-d'Or}} }} }}
{{PAGESINCAT: {{#titleparts: {{PAGENAME:Category:Côte-d'Or}} }} }}
,總是返回相同分類中的實際頁面數量。
解碼後的頁面名稱會儘可能標準化為MediaWiki支持的標準頁面名稱:
- 所有底線都自動替換為空格:
{{#titleparts: Talk:Foo/bah_boo|1|2}}
→ bah boo 不是bah_boo,儘管原來的內容有底線。
- 字串最多分割25此;更多的斜槓都會忽略,第25個元素將會包含字串的剩餘內容。 字串也限制在255個字元內,因為要被視為頁面標題:
{{#titleparts: a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/aa/bb/cc/dd/ee | 1 | 25 }}
→ y/z/aa/bb/cc/dd/ee- 如果出於某些原因確實要將此函數推到極限(儘管不太可能),可以透過巢狀函數呼叫來繞過只能分割25此的限制:
{{#titleparts: {{#titleparts: a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z/aa/bb/cc/dd/ee| 1 | 25 }} | 1 | 2}}
→ z
- 最後,第一個子字串根據本地wiki的大小寫設置進行大寫(如果該子字串也以本地命名空間名稱開頭,則該命名空間名稱也被標準化)。
{{#titleparts: talk:a/b/c }}
→ Talk:A/b/c
{{#titleparts: one/two/three/four|1|1 }}
→ One{{#titleparts: one/two/three/four|1|2 }}
→ two
如果需要小寫,使用lc:函數以控制輸出:
{{lc: {{#titleparts: one/two/three/four|1|1 }} }}
→ one
你可以在字串開頭添加一個「偽」斜槓以修正第一個子字串的大小寫。對於要返回的第一個分段,應使用2
而不是1
。
{{#titleparts: /one/two/three/four|1|2 }}
→ one{{#titleparts: /One/two/three/four|1|2 }}
→ One
{{#titleparts: {one/two} | 1 | 1 }}
→ {one/two}. 不產生預期的: {one{{#titleparts: [[page]]/123 | 1 | 2 }}
→ page/123. 不起作用,因為頁面標題中的中括號是非法的,並且此解析器函數不處理嵌入在其輸入的頁面名稱參數中的連結,即使使用了MediaWiki語法或任何其他HTML或MediaWiki標籤。{{#titleparts: red/#00FF00/blue | 1 | 3 }}
→ "". 不起作用,因為「#」在頁面標題中是非法的。
.
」或「..
」,那麼#titleparts不會解析字串:
{{#titleparts: one/./three | 1 | 1 }}
→ one/./three. 返回整個字串。不產生預期的: one
字串函數
所有這些函數(len
, pos
, rpos
, sub
, replace
, explode
)都融合在了StringFunctions擴充中,但是只有在管理員在LocalSettings.php
中啟用了$wgPFEnableStringFunctions = true;
的情況下才能使用。
所有這些函數都以O(n)的時間複雜度執行,使其能夠抵禦DoS攻擊。
- 這些函數的部分參數透過全域設置進行限制,以防止濫用。 參見後面的限制段落。
- 對於區分大小寫的函數,在某些情況下,可以使用魔術字
{{lc:string}}
來解決。 - 要確定MediaWiki伺服器是否啟用這些功能,請檢查Special:Version中支持的擴充解析器函數列表。
- 字串長度限制為
$wgPFStringLengthLimit
變數,預設為1000。
#len
#len
解析器函數是在1.2.0版本從nsp=0擴充合併的。#len函數返回指定字串的長度。 語法為:
{{#len:string}}
返回值始終是源string中的字元數量(擴充模板呼叫之後、轉換為HTML之前的字元數量)。 如果未指定字串,則返回值為零。
- 此函數可安全處理UTF-8多位元組字元。 例如:
8
→8
- 前導和尾隨的空格或換行不計算在內,但會考慮中間的空格和換行。 例如:
8
→8
20
→5
- 2個字元之間3個空格
- 透過引用給出的字元不會轉換,而是根據其源格式進行計數。
10
→6
- 命名的字元引用9
→5
- 數字字元引用,不被忽略,儘管它在此處指定了一個空格。
- 像
<nowiki>
和其他標籤擴充的長度總是為零,因為這些內容對解析器而言是隱藏的。 例如:37
→4
#pos
#pos
解析器函數是在1.2.0版本從nsp=0擴充合併的。#pos函數返回給定搜尋詞在字串中的位置。 語法為:
{{#pos:string|搜索词|offset}}
offset參數如果指定了,則會表明函數應該開始搜尋的起始位置。
如果找到了搜尋詞,則返回的值是字串string中的位置(從0開始數)。
如果沒有找到搜尋詞,函數返回空字串。
- 該函數是大小寫敏感的。
- 搜尋詞允許的最大長度限制取決於全域設置$wgStringFunctionsLimitSearch。
- 此函數可安全處理UTF-8多位元組字元。 範例:
{{#pos:Žmržlina|žlina}}
返回3。 - 像#len一樣,
<nowiki>
和其他標籤擴充在計算字元位置時都被視為長度為1。 例如:{{#pos:<nowiki>This is a </nowiki>test|test}}
返回1。
#rpos
#rpos
解析器函數是在1.2.0版本從nsp=0擴充合併的。#rpos函數返回給定搜尋詞在字串中的最後位置。 語法為:
{{#rpos:string|搜索词}}
如果找到了搜尋詞,則返回的值是字串string中的最後位置(從0開始數)。
如果沒有找到搜尋詞,函數返回-1。
使用该函数搜索最后一个分隔符时,给结果添加+1以检索最后一个分隔符之后的位置。 这在找不到分隔符时也有效,因为“-1 + 1”为零,也就是指定值的开头。
→ 使用該函數搜尋最後一個分隔符時,給結果添加+1以檢索最後一個分隔符之後的位置。 這在找不到分隔符時也有效,因為「-1 + 1」為零,也就是指定值的開頭。
- 該函數是大小寫敏感的。
- 搜尋詞允許的最大長度限制取決於全域設置$wgStringFunctionsLimitSearch。
- 此函數可安全處理UTF-8多位元組字元。 例如:
{{#rpos:Žmržlina|lina}}
返回4。 - 像#len一樣,
<nowiki>
和其他標籤擴充在計算字元位置時都被視為長度為1。 例如:{{#rpos:<nowiki>This is a </nowiki>test|test}}
返回1。
#sub
#sub
解析器函數是在1.2.0版本從nsp=0擴充合併的。#sub函數返回指定字串中的子字串(substring)。 語法為:
{{#sub:string|start|length}}
start參數,如果為正(或者零),則會指定要返回的第一個字元的索引(從0開始數)。
例如:
{{#sub:Icecream|3}}
返回cream
。
{{#sub:Icecream|0|3}}
返回Ice
。
如果start參數為負,則指定要返回從末尾開始的多少個字元。
例如:
{{#sub:Icecream|-3}}
返回eam
。
length參數,如果存在且為正數,則會指定返回的字串的最大長度。
例如:
{{#sub:Icecream|3|3}}
返回cre
。
如果length參數為負,則指定忽略從末尾開始的多少個字元。
例如:
{{#sub:Icecream|3|-3}}
返回cr
。
如果start參數為負,則指定要返回從末尾開始的多少個字元。 length參數,如果存在且為正數,則會指定返回的字串從開始點開始的最大長度。
例如:
{{#sub:Icecream|-3|2}}
返回ea
。
- 如果length參數為零,則完全不會用於截斷。
- 例如:
{{#sub:Icecream|3|0}}
返回cream
。{{#sub:Icecream|0|3}}
返回Ice
。
- 例如:
- 如果start表示一個超出了由負的length參數從末尾截斷的位置,則將返回一個空字串。
- 例如:
{{#sub:Icecream|3|-6}}
返回空字串
- 例如:
- 此函數可安全處理UTF-8多位元組字元。 例如:
{{#sub:Žmržlina|3}}
返回žlina
。 - 像#len一樣,
<nowiki>
和其他標籤擴充在計算字元位置時都被視為長度為1。 例如:{{#sub:<nowiki>This is a </nowiki>test|1}}
返回test
。
#count
#count
解析器函數是在1.2.0版本添加到nsp=0擴充中的。#count函數返回指定子字串在提供的文字中出現的次數。
{{#count:string|substring}}
#replace
#replace
解析器函數是在1.2.0版本從nsp=0擴充合併的。#replace函數返回指定的字串,並將所有搜尋詞出現的地方替換成替換詞。
{{#replace:string|search term|replacement term}}
如果search term未指定或者為空,則搜尋單個空格。
如果replacement term未指定或者為空,則所有search term都會從string中移除。
- 該函數是大小寫敏感的。
- search term允許的最大長度限制取決於全域設置$wgStringFunctionsLimitSearch。
- replacement term允許的最大長度限制取決於全域設置$wgStringFunctionsLimitReplace。
- 即使replacement term是空格,也會使用空字串。 * 這是MediaWiki解析器的副作用。 如要在replacement term中使用空格,將其放在nowiki標籤中。
- 例如:
{{#replace:My_little_home_page|_|<nowiki> </nowiki>}}
返回My little home page
。 - 如果不起作用,嘗試使用帶有兩個自我閉合標籤的
{{#replace:My_little_home_page|_|<nowiki/> <nowiki/>}}
。 - 注意在替換詞中這是唯一可以使用nowiki的地方',因為其他的nowiki都會被用來繞過$wgStringFunctionsLimitReplace,將任意大量的字串注入到輸出中。 因此,在替換詞中所有出現
<nowiki>
或其他標籤擴充的地方都會替換為空格。
- 例如:
- 此函數可安全處理UTF-8多位元組字元。 例如:
{{#replace:Žmržlina|ž|z}}
返回Žmrzlina
。 - 如果單個文字字串中的多個項都要替換,可以考慮Extension:ReplaceSet。 該擴充會添加一個空餘替換序列的解析器函數。
- 忽略大小寫的替換
當前該語法不提供開關大小寫敏感設置的選項。
但你可以使用格式化的魔術字來解決。
(例如,{{lc:你的字符串}}
)
例如,如果想從字串中刪除單詞「Category:」而不管其大小寫,可以輸入:
{{#replace:{{lc:{{{1}}}}}|category:|}}
但缺點就是輸出的都會變成小寫。 如果想在替換後保留大小寫,則必須使用多個巢狀級別(即多次替換呼叫)來實現相同的目的。
#explode
#explode
解析器函數是在1.2.0版本從nsp=0擴充合併的。#explode函數將指定的字串分成多個片段,返回其中一段。 語法為:
{{#explode:string|delimiter|position|limit}}
delimiter參數指定一個用來將string劃分成段的字串。 這個delimiter字串不是任何片段的一部分,如果有兩個delimiter彼此相鄰,會在二者之間建立一個空片段。 如果該參數未指定,則使用單個空格。 limit參數僅在解析器函數中可用,在獨立的字串函數版本中不可用,允許你限制返回的部分的數量,所有剩餘文字都包含在最終部分中。
position參數指定了返回哪一個片段。 片段是從0開始數的。 如果參數未指定,則使用第一個片段(數字0的片段)。 如果position使用負值,則片段會從最後開始數。 這種情況下,第-1個片段表示最後一段。 例如:
{{#explode:And if you tolerate this| |2}}
返回you
{{#explode:String/Functions/Code|/|-1}}
返回Code
{{#explode:Split%By%Percentage%Signs|%|2}}
返回Percentage
{{#explode:And if you tolerate this thing and expect no more| |2|3}}
返回you tolerate this thing and expect no more
返回的值是第position個片段。如果片段數量少於position指定的,則返回空字串。
- 該函數是大小寫敏感的。
- delimiter允許的最大長度限制由全域設置$wgStringFunctionsLimitSearch指定。
- 該函數可以安全處理UTF-8多位元組字元,例如
{{#explode:Žmržlina|ž|1}}
返回lina
。
#urldecode
#urldecode
將「URL編碼的跳脫字元轉換回原來的可讀字元。語法為:
{{#urldecode:值}}
注意:
- 該函數是透過直接暴露PHP的urldecode()函數來運作的。
- 字元代碼參考可參見www.w3schools.com。
- 與此相反的
urlencode
,已經融合在了MediaWiki的1.18版本中,具體範例可參見幫助:魔術字。 - urldecode是在2010年從字串函數透過commit 1b75afd18d3695bdb6ffbfccd0e4aec064785363合併的。
限制
本模組定義三個全域設置:
這些用於限制一些函數的部分參數以確保函數在O(n)時間複雜度內執行,因此可避免Dos攻擊,確保安全。
$wgString FunctionsLimitSearch
#pos、#rpos、#replace、#explode都使用了此設置。所有這些函數在執行時都會在更大的字串中搜尋子字串,這可以在O(n*m)內執行,因此使軟件更容易受到DoS攻擊。將此值設置為特定的更小的數,可將時間複雜度降低到O(n)。
此設置限制了所搜尋字串的最大允許長度。
預設值為30個多位元組字元。
$wgStringFunctionsLimitReplace
#replace使用了此設置。此函數將一個字串的所有出現的地方替換為另一個字串,這樣將能夠快速生成非常大量的數據,因此使軟件更容易受到DoS攻擊。此設置限制了替換字串的最大允許長度。
預設值為30個多位元組字元。
一般幫助
替換引用
在井號前面添加subst:
可以將字串函數替換引用:
{{subst:#ifexist: Help:解析器函数 | [[Help:解析器函数]] | Help:解析器函数 }}
→ 將在文字中插入代碼[[Help:解析器函数]]
,因為Help:解析器函數存在。
<ref>open…
內的替換引用不起作用,如要使用,可以使用</ref>
</ref>{{subst:#tag:ref|
…}}
。
重新導向
特別地,{{#time:
…|now-
…}}可以方便地重新導向到包含日期的頁面,但這不起作用。
在表格中跳脫管道符
解析器函數會破壞wikitable語法和管道字元(|
),將所有的原始管道字元視為參數分隔符。
為了避免這個,很多wiki使用模板Template:!,其內容僅為一個管道符(|
),自MediaWiki 1.24開始被{{!
魔術字}}取代。
這會從MediaWiki解析器中「隱藏」管道符號,確保在展開頁面上的所有模板和變數之前不考慮它。
然後將被解釋為表格的行或列分隔符。
你也可以使用原始的HTML表格語法,儘管這並不直觀而且容易出錯。
對於需要顯示的管道字元,可以使用HTML實體進行跳脫,顯示為純粹的、未被解釋的字元:|
。
說明 | 您輸入的 | 您輸出的 |
---|---|---|
將管道字元跳脫為表格行/列分隔符 | {{!}} |
| |
將管道字元跳脫為純字元 | | |
| |
除去空白字元
空白字元(whitespace),包括換行字元、制表符和空格,在這些解析器函數的所有參數的開頭和結尾處,都會被除去。如果不希望這樣,可以將字串放在引號中後進行比較。
{{#ifeq: foo | foo | equal | not equal }}
→ equal{{#ifeq: "foo " | " foo" | equal | not equal }}
→ not equal
要避免修整then和else部分,一些人為達到目的,會使用<nowiki> </nowiki>而非空格。
foo{{#if:|| bar }}foo
→ foobarfoofoo{{#if:||<nowiki /> bar <nowiki />}}foo
→ foo bar foo
然而,這種方法只能用於彩現單個空白字元,因為解析器函數會將一行中的多個空白字元擠壓成一個。
<span style="white-space: pre;">foo{{#if:||<nowiki/> bar <nowiki/>}}foo</span>
→ foo bar foo
在本例中,white-space: pre
樣式用來強制瀏覽器保留空白,但即使使用它,也不會顯示空格。發生這種情況是因為這些空格在傳送到瀏覽器之前,就已經被軟件除去了。
要解決此問題,可以將空白字元替換為 
(可折行空格)或者
(不可折行空格),因為這些字元不會被軟件修改:
<span style="white-space: pre;">foo{{#if:||   bar   }}foo</span>
→ foo bar foofoo{{#if:|| bar }}foo
→ foo bar foo
請注意,不是所有的參數都是一樣的。在解析器函數中,開頭和結尾的空白總是被剝離。在模板中,命名的參數和命名的非命名參數的開頭和結尾的空白會被剝離,但非命名的參數則不會。
foo
→ foo{{{1}}}foo模板链接:{{1x|content= bar }}
foofoo
→ foobarfoo模板链接:{{1x|1= bar }}
foofoo
→ foo bar foo模板链接:{{1x| bar }}
foo