帮助:解析函数
前言
本页介绍本WIKI内大部分解析函数(Parser Functions,由扩展插件(Extensions[1])通过Parser::setFunctionHook
定义[2][3])的用途和用法,扩展列表参照特殊:版本,MediaWiki原生函数基本参照[1]。本页面仅介绍简单的使用方法,详细文档请查看引用的源文页面。另外本页面编写中也参考了THBwiki[4]中的帮助:解析函数页面。
所有函数均适用的注意事项
以下是一个解析函数的基本格式:
{{#函数名: 参数1 | 参数2 | ... | 参数n }}
在页面中写上如此一般的代码后,后台解析页面是就会呼叫解析函数“函数名”,并传入相应的参数。如果输入的参数内同样的含有函数(或模板等需要展开运算的代码),解析器将会先运算和展开参数里的代码。这种先后次序与数学公式中的括号是同等效果,由内至外逐一展开运算。
其他注意事项:
- 某些函数对“该参数的值为空白”及“缺少该参数”的理解会有差异,导致运算处理和最终输出出现差错,需要留意该函数有没有这种设定。例如regex就有这种设定。
- 字符本身和对应的HTML实体(HTML Entity[5])不一定会受到一致的处理,甚至不会相互等于,需要留意函数是否会将输入解码或将输出编码。
- 如果函数突然出现不符合预期的输出,那很有可能是你忘记了对某些特殊字符转义。
- 参数内容的前后可以随意添加空格和换行,可以适当使用让排版更整齐易懂。
A
arraymap
来自Multi Array Map。
把输入字串以分隔符切开后逐个代入格式字串中求值,最后用输出分隔符串合输出。分隔符开头或结尾是空格时必须用nowiki包裹,输出分隔符也是如此,亦可以用\n表示换行。格式字串中可以随便使用模板和函数而不需要使用nowiki,所有运算都会在代入之后发生,只有使用管道符“|”的时候才必须使用“{{!}}
”(花括号同理)。如需处理二维阵列请用#multimap。
- 格式
{{#arraymap: 字串 | 分隔符(默认为“,”) | 代号 | 格式字串 | 输出分隔符(默认为“, ”,注意有空格) }}
- 例子
{{#arraymap:22;33;小电视|;|@|<font color=red>@</font>|,}}
→22,33,小电视
arraymaptemplate
来自Multi Array Map。
arraymap的模板变体,切开后会输入模板再以分隔符串合输出。如需处理二维阵列请用#multitem。
- 格式
{{#arraymaptemplate: 字串 | 模板名 | 分隔符(默认为“,”) | 输出分隔符(默认为“, ”,注意有空格) }}
- 例子
anchorencode
MediaWiki原生函数。
把输入的字串转换成锚点编码,即是网址栏中#号后面的文字,可以用于生成锚点链接,但一般情况只需要[[词条名#锚点]]
就行了。
- 格式
{{anchorencode: 锚点字串 }}
- 例子
{{anchorencode: 字串 }}
→字串
{{anchorencode: ABC中文 英文 123&456+1% }}
→ABC中文_英文_123&456+1%
C
CSS
E
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
|
来自ParserFunctions。
用于验证一个数学表达式,并返回它的计算值。
此函数在Scribunto扩展中也可用,函数名为mw.ext.ParserFunctions.expr
。
- 格式
{{#expr: 表达式 }}
- 支持的运算符如右方表格所示,表格从上到下按运算符的计算优先顺序排列。
- 每个运算符的详细功能见Help:Calculation。
- 计算结果的精度和格式取决于wiki服务器的操作系统,和网站语言的数字格式。
- 例子
- 当用于计算布尔代数值(Boolean algebra)时,零值表示
false(假)
,任何非零值,无论正负,都表示ture(真)
:{{#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|iferror]]函数捕捉到:
{{#expr: }}
→{{#expr: 1+ }}
→表达式错误:缺少+的操作数。
{{#expr: 1 = }}
→表达式错误:缺少=的操作数。
{{#expr: 1 foo 2 }}
→表达式错误:无法识别的词语“foo”。
- 加减运算符在数字之前与之后的意义不同,它们有可能被当作正负号,而不会被当作不正确的表达式:
{{#expr: +1 }}
→1
{{#expr: -1 }}
→-1
{{#expr: + 1 }}
→1
{{#expr: - 1 }}
→-1
- 注意
- 如果使用魔术字的输出值,必须使用其原始格式,如:移除所有分割逗号,转换为数字。
- 比如
{{NUMBEROFUSERS}}
输出的是15,700,564
,但是实际需要的是15700564
,原始格式可以用{{formatnum:{{NUMBEROFUSERS}}|R}}
来得到,详见formatnum。例子如下:{{#expr:{{NUMBEROFUSERS}}+100}}
→表达式错误:无法识别的符号“,”。
{{#expr:{{formatnum:{{NUMBEROFUSERS}}|R}}+100}}
→15700664
- 注意
- 运算符
mod
会在某些除数值下给出错误的结果:{{#expr: 123 mod (2^64-1)}}
→零除。
(返回空字串,结果本应是123
)
- 补充
- 若想要进行关于日期的计算(比如:将当前日期与某日期进行比较),首先应将时间转化为“1970年1月1日之后多少秒”的结构,可以使用
{{#time: xNU }}
来转换(详见time),然后就可以把日期当作数字来进行计算和比较了。 - 关于四舍五入
- 将运算符
round
左边的数四舍五入,使其小数位数为round
右边的数。 - 如需进一取整(向上舍入),使用
ceil
;如需舍去取整(向下舍入),使用floor
。
例子 | 结果 | 舍入方法 |
---|---|---|
{{#expr: 1/3 round 5 }} |
0.33333 | 保留5位小数。舍去的部分首位数值<5,则不会进一。 |
{{#expr: 1/6 round 5 }} |
0.16667 | 保留5位小数。舍去的部分首位数值≥5,则进一。 |
{{#expr: 8.99999/9 round 5 }} |
1 | 同上方法,结果是进一得到的。 |
{{#expr: 1234.5678 round -2 }} |
1200 | 此处保留到百位。要保留到小数点左侧,应使用负的位数。 |
{{#expr: 1234.5678 round 2 }} |
1234.57 | 此处保留到百分位。要保留到小数点右侧,应使用正的位数。 |
{{#expr: 1234.5678 round 2.3 }} |
1234.57 | 位数值如果输入了带小数的数值,小数部分不起作用。 |
{{#expr: trunc 1234.5678 }} |
1234 | 保留到整数可以使用trunc 。
|
保留到整数的舍入规则: | ||
{{#expr: 1/3 round 0 }} |
0 | 保留到最近的整数,向下舍入至零。 |
{{#expr: 1/2 round 0 }} |
1 | 保留到最近的整数,向上舍入至一。 |
{{#expr: 3/4 round 0 }} |
1 | 保留到最近的整数,向上舍入至一。 |
{{#expr: -1/3 round 0 }} |
-0 | 保留到最近的整数,向上舍入至零。 |
{{#expr: -1/2 round 0 }} |
-1 | 保留到最近的整数,向下舍入至负一。 |
{{#expr: -3/4 round 0 }} |
-1 | 保留到最近的整数,向下舍入至负一。 |
使用ceil 和floor 时的舍入规则:
| ||
{{#expr: ceil(1/3) }} |
1 | 向上舍入至一。 |
{{#expr: floor(1/3) }} |
0 | 向下舍入至零。 |
{{#expr: ceil(-1/3) }} |
-0 | 向上舍入至零。 |
{{#expr: floor(-1/3) }} |
-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
L
lc
MediaWiki原生函数。
把输入的字串中所有字母变成小写。
- 格式
{{lc: 字串 }}
- 例子
{{lc: A字串 BC }}
→a字串 bc
lcfirst
MediaWiki原生函数。
把输入的字串中第一个字母变成小写。
- 格式
{{lcfirst: 字串 }}
- 例子
{{lcfirst: A字串 BC }}
→a字串 BC
{{lcfirst: 字串 BC }}
→字串 BC
I
if
来自ParserFunctions。
用于鉴别一个测试字串是否为空。一个只含有空白字符的字串会被判定为空。
- 格式
{{#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
- 最后一个参数(字串空输出值)可以省略。
{{#if: foo | yes }}
→yes
{{#if: | yes }}
→{{#if: foo | | no}}
→
- 这个函数可以被嵌套。嵌套时,需用完整格式的
#if
函数,替代外层#if
函数的某个参数。最大可以嵌套七层,具体取决于网站和存储限制。{{#if: 测试字串1 | 字串1非空输出值 | {{#if: 测试字串2 | 字串2非空输出值 | 字串2空(或只有空白字符)输出值 }} }}
- 可以用一个参数当作#if函数的测试字串。必须在变量名的后面加上管道符
|
。{{#if:{{{1|}}}| 变量1中输入了文本 | 变量1中没有文本 }}
- 对于在模板中的应用,更多例子可参照:Help:Parser functions in templates
ifeq
来自ParserFunctions。
用于比较两个字串是否相同。
- 格式
{{#ifeq: 测试字串1 | 测试字串2 | 相同时输出值 | 不相同时输出值 }}
- 例子
- 如果两个字串都是有效的数值,则会按照数值进行比较。
{{#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
函数的区别)
- 注意
#ifeq
和#switch
的数值比较与使用#expr
进行比较不同:{{#ifeq: 12345678901234567 | 12345678901234568 | equal | not equal}}
→not equal
{{#switch: 12345678901234567 | 12345678901234568 = equal | not equal}}
→not equal
- 因为PHP以整数型比较两个数字,然而:
{{#ifexpr: 12345678901234567 = 12345678901234568 | equal | not equal}}
→equal
- 因为MediaWiki转换文本数字为浮点型,对于比较大的整数,会导致末尾被舍去。
- 注意
- 在解析函数内部的标签和解析函数(如
<nowiki>
)会被暂时替换为一个唯一的代码。这会影响到比较结果:{{#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}}
)比较当前页面标题时,应小心。这些变量会将特殊字符转换为数字HTML实体。这会造成具有误导性的结果。比如,在一个标题为“L'Aquila”的页面上:{{#ifeq: L'Aquila | {{FULLPAGENAME}} | equal | not equal}}
→not equal
- 上面的结果实际是错误的。经过改进之后,现在它会返回“
equal
”。但是对于其他情况可能不会如此。如{{FULLPAGENAME}}
,在部分网站,可能会将第一个字母替换为大写,可能会将所有下划线替换为空格。 - 为了解决这个问题,可以在两个参数上都应用变量:
{{#ifeq: {{FULLPAGENAME: L'Aquila}} | {{FULLPAGENAME}} | equal | not equal}}
→equal
ifexist
这个函数将一组字符串作为输入,并翻译成页面标题,然后根据在本地wiki上是否存在该页面而返回对应的值。
{{#ifexist: page title | value if exists | value if doesn't exist }}
只要页面存在就会判定为true
(真值),即便那个页面看上去是空白的(比如像是分类链接或者是魔术字解释页之类的却不包含任何可视内容的页面),或者是重定向页,或者它就是空白页。当且仅当页面是红链时判定为false
(假值),包括那些曾经存在却被删除的页面。
{{#ifexist: Help:Extension:ParserFunctions/zh | exists | doesn't exist }}
→ exists{{#ifexist: XXHelp:Extension:ParserFunctions/zhXX | exists | doesn't exist }}
→ doesn't exist
函数在系统消息对应模块被安装时认定为true
,对特殊页面的判定则取决于本地软件自身。
{{#ifexist: Special:Watchlist | exists | doesn't exist }}
→ exists{{#ifexist: Special:CheckUser | exists | doesn't exist }}
→ exists (因为Checkuser扩展已经安装于此wiki){{#ifexist: MediaWiki:Copyright | exists | doesn't exist }}
→ exists (因为MediaWiki:Copyright已被自定义)
如果一个页面使用了#ifexist:
来检查目标页面,则这个检查页面将出现在被检查页面的Special:WhatLinksHere里。所以如果本页面(Help:Extension:ParserFunctions/zh)使用了代码 {{#ifexist:Foo}}
,那么Special:WhatLinksHere/Foo将列出Help:Extension:ParserFunctions/zh。
若wiki有其在使用的对应的共享媒体库,#ifexist:
就可用于检查一个文件是否在媒体库中,而不仅仅只是在wiki本体上检查:
{{#ifexist: File:Example.png | exists | doesn't exist }}
→ doesn't exist{{#ifexist: Image:Example.png | exists | doesn't exist }}
→ doesn't exist{{#ifexist: Media:Example.png | exists | doesn't exist }}
→ exists
如果文件有一个已创建的对应的本地描述页面,上面的结果将全部是exists。
#ifexist:
不会对跨wiki链接起作用。
ifexist 限制
#ifexist:
被视为“高开销(expensive)解析器函数”,每个页面调用这类函数的次数(包括包含于嵌入式模板的函数)存在一个限制。当达到该限制时,对于多出该限制的#ifexist:
函数,无论其目标页面是否存在,函数只会自动返回错误值false,且该页面会被分类到Category:Pages with too many expensive parser function calls中。追踪分类可能因您的wiki内容的语言而异。
在某些案例中,在css中,利用选择器a.new
(以选出链接到不存在的页面的链接)或者是a:not(.new)
(以选出已存在页面的链接),是可以达到模仿ifexist的效果的。另外,控制$wgExpensiveParserFunctionLimit
可以调整对高开销解析器函数数量的限制,如果有需要,也可以增加页面LocalSettings.php中的限制值。
ifexisit和需要的页面
一个不存在的页面被#ifexist检测后会被计数在待创建页面中。 请参阅任务T14019了解原因,并查看w:Template:Linkless exists以了解解决方法。
P
padleft
将参数1通过在左侧补上参数3指定的字符串(默认为0)补足到参数2指定的长度,例如 044
生成 044。参数3指定的字符串可能被截断以保证补足后的字符串长度满足要求。
- 例子&输出
{{padleft:xyz|5}}
→ 00xyz
{{padleft:xyz|5|_}}
→ __xyz
{{padleft:xyz|5|abc}}
→ abxyz
{{padleft:xyz|2}}
→ xyz
{{padleft:|1|xyz}}
→ x
padright
S
switch
来自ParserFunctions。
这个函数将一个输入值与若干个情况值对比,如果找到了相符的情况,则返回该情况下的输出字串。
- 格式
{{#switch: 比较字串 | 情况字串1 = 返回结果1 | 情况字串2 = 返回结果2 | ... | 情况字串n = 返回结果n | 默认结果 }}
- 例子
{{#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
和部分转换标签可以作用于配置文件,从而可以使不熟悉模板代码的编辑者编辑可配置元素。- 关于默认结果
- 在当没有'情况字串'与'比较字串'相符时,会返回'默认结果':
{{#switch: test | foo = Foo | baz = Baz | Bar }}
→Bar
- 按这个函数的句法,'默认结果'必须是最后一个参数,并且不能包含原始等号符。
{{#switch: test | Bar | foo = Foo | baz = Baz }}
→{{#switch: test | foo = Foo | baz = Baz | B=ar }}
→
- 或者'默认结果'可以用'情况字串'
#default
来特别声明。
{{#switch: 比较字串 | 情况字串1 = 返回结果1 | 情况字串2 = 返回结果2 | ... | 情况字串n = 返回结果n | #default = 默认结果 }}
- 用这种方式声明的'默认结果'可以放在函数内的任何位置:
{{#switch: test | foo = Foo | #default = Bar | baz = Baz }}
→Bar
- 如果'默认结果'被省略,当没有相符情况时,不会返回结果:
{{#switch: test | foo = Foo | baz = Baz }}
→
- 一组情况的结果
- 可以使用“fallthrough”值,即若干'情况字串'返回相同的'返回结果'。这能减少重复。
{{#switch: 比较字串 | 情况字串1 = 返回结果1 | 情况字串2 | 情况字串3 | 情况字串4 = 返回结果234 | 情况字串5 = 返回结果5 | 情况字串6 | 情况字串7 = 返回结果67 | #default = 默认结果 }}
- 在这里情况2、3、4都会返回'返回结果234',情况6、7都会返回'返回结果67'。
- 关于比较
- 与
#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
- '情况字串'可以是空:
{{#switch: | = Nothing | foo = Foo | Something }}
→Nothing
- 当出现一个相符情况后,之后的'情况字串'会被忽略:
{{#switch: b | f = Foo | b = Bar | b = Baz | }}
→Bar
- 注意
#switch
和#ifeq
的数值比较方法与表达式比较不同:{{#switch: 12345678901234567 | 12345678901234568 = A | B}}
→B
{{#ifexpr: 12345678901234567 = 12345678901234568 | A | B}}
→A
- 具体见
ifeq
处的第一条“注意”。 - 关于原始等号符
- '情况字串'不能包含原始等号符。为了解决这个问题,创建了一个只包含一个等号符
=
的模板{{=}}
。 - 应用的例子:
{{#switch: 1=2 | 1=2 = raw | 1=2 = nowiki | 1=2 = html | 1{{=}}2 = template | default }}
→ html
- 关于替换
#ifeq
#switch
可以用来减少扩展深度。- 比如:
{{#switch:{{{1}}} |情况1=分支1 |情况2=分支2 |情况3=分支3 |分支4}}
- 等价于:
{{#ifeq:{{{1}}}|情况1 |分支1 |{{#ifeq:{{{1}}}|情况2 |分支2 |{{#ifeq:{{{1}}}|情况3 |分支3 |分支4}}}}}}
- 写成便于阅读的格式即为:
{{#ifeq:{{{1}}}|情况1
|<!--then-->分支1
|<!--else-->{{#ifeq:{{{1}}}|情况2
|<!--then-->分支2
|<!--else-->{{#ifeq:{{{1}}}|情况3
|<!--then-->分支3
|<!--else-->分支4}}}}}}
subst
T
tag
U
uc
MediaWiki原生函数。
把输入的字串中所有字母变成大写。
- 格式
{{uc: 字串 }}
- 例子
{{uc: a字串 bc }}
→A字串 BC
ucfirst
MediaWiki原生函数。
把输入的字串中第一个字母变成大写。
- 格式
{{ucfirst: 字串 }}
- 例子
{{ucfirst: a字串 bc }}
→A字串 bc
{{ucfirst: 字串 bc }}
→字串 bc