2023年政策修订增补工作正在进行中,欢迎参与!
  • Moegirl.ICU:萌娘百科流亡社群 581077156(QQ),欢迎对萌娘百科运营感到失望的编辑者加入
  • Moegirl.ICU:账号认领正在试运行,有意者请参照账号认领流程

使用者:Selfice/圖書館/幫助:擴展:解析器函數(上)

萌娘百科,萬物皆可萌的百科全書!轉載請標註來源頁面的網頁連結,並聲明引自萌娘百科。內容不可商用。
跳至導覽 跳至搜尋

#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

這個函數計算數學表達式並返回計算值。 在Scribunto中可以通過mw.ext.ParserFunctions.expr來使用此函數。

{{#expr: 表达式 }}

右表依優先級列出了支持的運算符,運算符的詳細說明請見幫助:計算。運算結果的精度和格式受運行wiki伺服器作業系統和站點語言的數字格式影響可能存在差異。 如果你想要進行基於日期時間的計算(如檢測當前日期時間是否超過指定日期時間),首先用1719461408將日期時間轉換為距1970年1月1日的秒數,再對秒數進行加減運算。

四捨五入

將左邊的數字四捨五入為1/10的冪的倍數,指數等於右邊給出的數字的截斷值(truncated value)。

向上、向下取整分別使用ceilfloor

案例 結果 捨入方式
{{#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" }}Expression error: Unrecognized punctuation character """.
{{#expr: a = a }}Expression error: Unrecognized word "a".
{{#ifeq: a | a | 1 | 0 }}1


#if

語法:{{#ifeq: 字符串1 | 字符串2 | 相同时输出值 | 不相同时输出值 }}

常用用法:

  • {{#ifeq:{{{是否实装}}}|是|[[文件:{{{角色名称}}}.png]]| 暂未实装}}

這個函數判斷一個字符串是否為空。只包含空格的字符串被視為空字符串。

{{#if: 测试字符串 | 测试字符串非空时的取值 | 测试字符串为空或仅包含空白字符时的取值 }}
{{#if: 参数1 | 参数2 | 参数3 }}

這個函數首先判斷參數1是否為空。如果參數1不為空,則輸出參數2。如果參數1為空或只包含空白內容(空格、換行等),則輸出參數3。

{{#if: | yes | no}}no
{{#if: string | yes | no}}yes
{{#if:      | yes | no}}no
{{#if:| yes | no}}no

字符串內容會被處理為純文本,因此不會計算數學表達式:

{{#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自身限制和內存限制而有變動。

$code1: 測試字符串 | 字符串非空時的值 | $code2: 測試字符串 | 字符串非空時的值 | 字符串為空(或只有空格)的值 $code3
{{#if: test string | value if test string is not empty | {{#if: test string | value if test string is not empty | value if test string is empty (or only white space) }} }}

你可以在#if條件句中以字符串變量代替測試字符串。在這裡,你需要在變量名的後面加上$pipe (分隔符)以正確引用字符串。 (因此如果參數沒有值,則計算結果為一個空字符串而非"{{{1}}}"。)

{{#if:{{{1|}}}|你在变量1里面输入了文本|变量1里面没有文本}}

參見幫助:模板中的解析器函數以了解更多關於解釋器函數中變量的相關例子。


#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
警告: 在數值比較結果上,#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將兩個數依字面表達理解成了浮點數,而對於像這樣的大數,轉換為浮點數由於精度誤差會存儲為一樣的數值,導致出錯。

警告: 任何的解析器標籤和其它的解釋器函數,用在解析器函數中時,都一定會被一個臨時生成的獨一無二的標識碼替代。這會影響如下比較:
{{#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如果被比較的字符串由相等的模板調用提供,且模板包含這些標籤,則條件視為真,但如果是兩個不同的模板,即使有包含這些內容的相同內容,也是視為假。
警告: 隨網站配置的變化,含有頁面名字的魔術字的字符串的字面比較可能會發生錯誤。 比如說,{{FULLPAGENAME}}這一魔術字隨wiki的變化,可能在返回時使開頭字母變成大寫,也會用下劃線替代空格。

為了解決這個問題,將這個魔術字應用到兩個參數上:

{{#ifeq: {{FULLPAGENAME: L'Aquila}} | {{FULLPAGENAME}} | equal | not equal}}equal


#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}}}」作為樣例。 ((如果沒有管道符,且參數不存在或沒有值,則參數就會顯示為這樣。) 參見幫助:模板中的解析器函數。)

{{#switch: {{{1}}} | foo = Foo | baz = Baz | Bar }}

上面的例子中,如果{{{1}}}等於foo,函數返回Foo。 如果等於baz,函數返回Baz。 如果參數是空的或者不存在,函數返回Bar

上面的這些中,也可以將樣例組合起來以返回單個結果。

{{#switch: {{{1}}} | foo | zoo | roo = Foo | baz = Baz | Bar }}

如果{{{1}}}等於foozooroo,函數返回Foo。 如果等於baz,函數返回Baz。 如果參數是空的或者不存在,函數返回Bar

而且,如果你希望在測試參數不能匹配任何樣例時不返回任何內容,可以省略默認結果。

{{#switch: {{{1}}} | foo = Foo | bar = Bar }}

在本例中,如果{{{1}}}存在且等於foobar,則分別返回FooBar,否則不返回任何內容。

這樣做相當於將默認值聲明為空。

{{#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標識碼&#61;來代替。

例如:

您輸入的 您輸出的
{{#switch: 1=2
  | 1=2 = raw
  | 1<nowiki>=</nowiki>2 = nowiki
  | 1{{=}}2 = template
  | default
 }}
template
{{#switch: 1=2
  | 1&#61;2 = html
  | default
 }}
html

為助您理解,您可以檢查模板:NBA球隊代表色。模板:擴展和w:Template:BOTREQ是兩個使用該函數的複雜例子。

替換#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
     }}
   }}
 }}

下轉User:Selfice/圖書館/幫助:擴展:解析器函數(下)