Extension:滥用过滤器/规则格式
該規則是自定義的語言,其格式与类C/JAVA/Perl语言的条件式十分相近。
字符串
宣告变量时,你可以将值填写在单引号或双引号中(字符串常量),亦可直接填写(数字变量,包括整型与浮点型浮點數)。
你可以使用\n
插入换行字元、\t
插入製表符(Tab),也可以使用半形反斜線来跳脫引號字元。
- 範例
"这是一条字符串/這是一個字串"
'这也是一条字符串/這也是一個字串'
'单引号\'可以\'存在于字串里/單引號\'可以\'存在於字串內'
"这是一条带有\n换行符的字符串/這是一個帶有\n換行字元的字串"
1234
1.234
-123
用戶自訂變數
你可以定義自訂的變數,只要在一行中使用賦值符號:=
(以;
結尾)並跟隨一個條件。
這些變數可以使用字母、底線和數字(除第一個字符外),並且不區分大小寫。
例如(來自w:Special:AbuseFilter/79):
(
line1:="(\{\{(r|R)eflist|\{\{(r|R)efs|<references\s?/>|</references\s?>)";
rcount(line1, removed_lines)
) > (
rcount(line1, added_lines)
)
数组
防濫用過濾器支援非關聯式陣列,如以下範例一樣使用。
小心: | 像page_namespace in [14, 15] 这样的表达式可能无法正常工作。 如果page_namespace 是1,4或5,则此值也将评估为true。 有关更多信息和可能的解决方法,请参阅T181024。 |
my_array := [ 5, 6, 7, 10 ];
my_array[0] == 5
length(my_array) == 4
int( my_array ) === 4 // 與length相同
float( my_array ) === 4.0 // 計算元素數量
string(my_array) == "5\n6\n7\n10\n" // 注意:最後一個換行將在未來移除
5 in my_array == true
'5' in my_array == true
'5\n6' in my_array == true // 注意:與陣列轉型為字串的方式相同,即使用換行來implode陣列。
1 in my_array == true // 注意:因為「in」指令將變數轉型為字串,所以 1 在 10 中被找到且回傳 true。
my_array[] := 57; // 這會在陣列末尾添加一個元素
my_array === [ 5, 6, 7, 10, 57 ]
my_array[2] := 42; // 這是更改陣列的元素
my_array === [ 5, 6, 42, 10, 57 ]
註解文字
您可以使用以下語法來加入註解:
/* 這是一條注釋 */
算术
你可以使用基本的算术符号对變數和常數进行算术运算,语法规则如下:
-
– 用左運算元减去右運算元。+
– 将左、右運算元相加。*
– 将左、右運算元相乘。/
– 用右運算元來除左運算元。**
– 对左運算元求幂,幂次由右運算元指定。%
– 回傳左運算元除以右運算元后的余数。
回傳結果的類型與PHP回傳的結果相同,可以在線上找到大量說明文件。 更多詳盡的例子可以在此AF解析器測試中找到。
示例 | 结果 |
---|---|
1 + 1 |
2 |
2 * 2 |
4 |
1 / 2 |
0.5 |
9 ** 2 |
81 |
6 % 5 |
1 |
布林运算
你可以要求满足所有条件为真,或满足任一条件为真,或只满足任一条件为真。
x | y
— OR – 如果两个条件中有一个或多个为真,则傳回True。x & y
— AND – 如果两个条件中所有条件都为真,则返回真值True。x ^ y
— XOR – 如果两个条件中当且仅当一个条件为真,则返回真值True。!x
— NOT – 如果条件为假,则回傳True。
範例
代码 | 结果 |
---|---|
1 | 1
|
true |
1 | 0
|
true |
0 | 0
|
false |
1 & 1
|
true |
1 & 0
|
false |
0 & 0
|
false |
1 ^ 1
|
false |
1 ^ 0
|
true |
0 ^ 0
|
false |
!1
|
false |
!0
|
true |
简单的比较
<
、>
– 如果左運算元分別小於/大於右運算元,則返回true。 注意:運算元會被轉換為字串,就如同在PHP發生的一樣,null < 任何數值 === true
且null > 任何數值 === false
。<=
、>=
– 如果左運算元分別小於或等於/大於或等於右運算元,則回傳true。 注意:運算元會被轉換為字串,就如同在PHP發生的一樣,null <= 任何數值 === true
且null >= 任何數值 === false
。==
(或=
)、!=
—如果左運算元分別等於/不等於右運算元,則回傳true。===
、!==
– 如果左運算元等於右運算元且左運算元的資料類型等於右運算元的資料類型,則回傳true,只要有一個不符合,回傳false。
示例 | 结果 |
---|---|
1 == 2 |
false |
1 <= 2 |
true |
1 >= 2 |
false |
1 != 2 |
true |
1 < 2 |
true |
1 > 2 |
false |
2 = 2 |
true |
'' == false |
true |
'' === false |
false |
1 == true |
true |
1 === true |
false |
['1','2','3'] == ['1','2','3'] |
true |
[1,2,3] === [1,2,3] |
true |
['1','2','3'] == [1,2,3] |
true |
['1','2','3'] === [1,2,3] |
false |
[1,1,''] == [true, true, false] |
true |
[] == false & [] == null |
true |
['1'] == '1' |
false[1] |
內建變數
防滥用过滤器可以根据變數的名称将各种變數传送给解析器。 你可以输入这些變數的名称来取用它们,就像取用常數一样。 在过滤日志中,你还可以看到各种请求的相关變數。
來自防濫用過濾器的變數
任何情況皆可用的變數
小心: | 與用戶相關的變數永遠可用,除了這種情況:未登入的帳號建立者。 所有以user_ 開頭的變數皆受影響,但user_type 除外。 |
描述 | 名称 | 資料型態 | 註釋 | ||
---|---|---|---|---|---|
動作 | action |
字符串 | 以下之一: edit, move, createaccount, autocreateaccount, delete, upload[2], stashupload[3] | ||
Unix变更时间戳 | timestamp |
字符串 | 使用 int(timestamp) 來取得整數以用來計算日期、時間、星期等等。 | ||
Wiki的数据库名称($1) | wiki_name |
字符串 | 例如,在英語維基百科上為「enwiki」,在義大利語維基語錄上為「itwikiquote」。 | ||
Wiki的语言代码($1) | wiki_language |
字符串 | 例如,在英語維基百科上為「en」,在義大利語維基語錄上為「it」。多語言維基例如維基共享資源、元維基、維基數據也回傳「en」。 | ||
用户编辑次数($1) | user_editcount |
整數/Null | 未註冊之使用者為Null。 | ||
用户账号名称($1) (IP in case the user is not registered) | user_name |
字符串 | 如果在"createaccount"和"autocreateaccount"動作時想取得被建立的帳戶名,請使用
accountname 。
| ||
账号类型($1) | user_type |
字符串 | 用户的类型,是ip 、temp (如果用户使用的是临时账户 )、named 、external 或unknown 中的其中一种。
| ||
确认电子邮件地址的时间($1) | user_emailconfirm |
字符串或null | 以YYYYMMDDHHMMSS的格式。 若電子郵件未確認則為Null。 | ||
用户账号年龄($1) | user_age |
整数 | 單位為秒。 未註冊之使用者為0。 | ||
用户是否被封禁($1) | user_blocked |
布尔值 | 已封鎖之註冊使用者為True。 對於來自被封鎖IP地址的編輯也是如此,即使編輯者是未被封鎖的已註冊使用者。 否則為False。 這無法區分部分封鎖和全站封鎖。
| ||
用户所在的组(包括隐藏组)($1) | user_groups |
字符串数组 | 参见Special:ListGroupRights | ||
用户拥有的权限($1) | user_rights |
字符串数组 | 参见Special:ListGroupRights | ||
页面ID($1) | article_articleid |
整数 | (已弃用) 請使用page_id 。
| ||
页面ID($1) (可通过侧边栏的“页面信息”链接查看) | page_id |
整数 | 这对新网页来说是 0,但在检查过去的点击时就不一定可靠了。 如果您在检查过去的点击时需要精确的结果,请使用「page_age == 0」来识别新创建的页面。 (請注意它速度較慢。) 此问题已在9369d08中修复,并于2023年9月11日合併。 | ||
页面命名空间($1) | article_namespace |
整数 | (已弃用) 請使用page_namespace 。
| ||
页面命名空间($1) | page_namespace |
整数 | 參見名字空间索引 Check for namespace(s) using expressions like "page_namespace == 2" or "equals_to_any(page_namespace, 1, 3)" | ||
页面年龄(秒)($1) | page_age |
整数 | 第一次编辑之后的秒数(新页面为0) 這是可靠的,但通常很慢;如果您不需要太高的精確度,請考慮使用page_id 。
| ||
不包含命名空间的页面标题($1) | article_text |
字符串 | (已弃用) 請使用page_title 。
| ||
不包含命名空间的页面标题($1) | page_title |
字符串 | |||
完整页面标题($1) | article_prefixedtext |
字符串 | (已弃用) 請使用page_prefixedtitle 。
| ||
完整页面标题($1) | page_prefixedtitle |
字符串 | |||
页面的编辑保护等级($1) | article_restrictions_edit |
字符串 | (已弃用) 請使用page_restrictions_edit 。
| ||
页面的编辑保护等级($1) | page_restrictions_edit |
字符串数组 | |||
页面的移动保护等级($1) | article_restrictions_move |
字符串 | (已弃用) 請使用page_restrictions_move 。
| ||
页面的移动保护等级($1) | page_restrictions_move |
字符串数组 | |||
文件的上传保护($1) | article_restrictions_upload |
字符串 | (已弃用) 請使用page_restrictions_upload 。
| ||
文件的上传保护($1) | page_restrictions_upload |
字符串数组 | |||
页面的创建保护($1) | article_restrictions_create |
字符串 | (已弃用) 請使用page_restrictions_create 。
| ||
页面的创建保护($1) | page_restrictions_create |
字符串数组 | |||
最后十位为该页面做出贡献的用户($1) | article_recent_contributors |
array of strings | (已弃用) 請使用page_recent_contributors 。
| ||
最后十位为该页面做出贡献的用户($1) | page_recent_contributors |
字符串数组 | 這通常很慢(參見#效能)。 嘗試在此之前使條件更可能被判斷為false,以避免不必要地執行此查詢。 若該頁面僅由一位使用者貢獻則為空值(不確定),最多統計100個歷史版本 | ||
第一个为页面做出贡献的用户($1) | article_first_contributor |
字符串 | (已弃用) 請使用page_first_contributor 。
| ||
第一个为页面做出贡献的用户($1) | page_first_contributor |
字符串 | 這通常很慢(參見#效能)。[4] 嘗試在此之前使條件更可能被判斷為false,以避免不必要地執行此查詢。 |
對部分動作可用的變數
小心: | 始终检查要使用的变量是否可用于当前要过滤的操作,例如通过使用action 变量。 Failing to do so (for instance using accountname for an edit, or edit_delta for a deletion) will make any code using the variable in question return false. |
描述 | 名称 | 資料型態 | 備註 |
---|---|---|---|
编辑摘要/原因($1) | summary |
字符串 | MediaWiki自動建立的摘要(「新章節」、「清空全部内容」等)是在過濾器檢查編輯後建立的,所以即使除錯工具顯示它們應被捕獲,但實際上不會被捕獲。 The variable contains whatever the user sees in the edit summary window, which may include MediaWiki preloaded section titles.[5] |
minor_edit |
停用,且對於2016到2018年間的所有項目皆被設為false。[6] | ||
编辑之前的旧页面的wikitext($1) | old_wikitext |
字符串 | 這個變數可能非常大。 盡可能考慮使用removed_lines 來提高性能。
|
编辑之后的新页面的wikitext($1) | new_wikitext |
字符串 | 這個變數可能非常大。 盡可能考慮使用added_lines 來提高性能。
|
编辑产生的差异($1) | edit_diff |
字符串 | |
编辑的统一变更差异(已预保存转换)($1) | edit_diff_pst |
字符串 | 這通常很慢(參見#效能)。 檢查added_lines 和removed_lines 可能更有效率。[7]
|
新页面大小($1) | new_size |
整数 | |
旧页面大小($1) | old_size |
整数 | |
编辑前后的大小变化($1) | edit_delta |
整数 | |
编辑中添加的行(已经过预保存转换)($1) | added_lines_pst |
字符串数组 | 盡可能使用added_lines ,更有效率。
|
编辑中添加的行($1) | added_lines |
字符串数组 | 最後差異中所有以+開頭的行 |
编辑中删除的行($1) | removed_lines |
字符串数组 | |
新文本中的所有外部链接($1) | all_links |
字符串数组 | This tends to be slow (see #Performance). |
编辑之前页面中的链接($1) | old_links |
字符串数组 | This tends to be slow (see #Performance). |
编辑中添加的所有外部链接($1) | added_links |
字符串数组 | 這通常很慢(參見#效能)。 考慮首先檢查added_lines ,再檢查added_links ,以減少變慢的編輯。 這遵守MediaWiki的外部連結規則 。 添加到陣列中的連結都是唯一的。 更改連結將計為1個添加和1個移除連結。
|
编辑中删除的所有外部链接($1) | removed_links |
字符串数组 | 這通常很慢(參見#效能)。 考慮首先檢查removed_lines ,再檢查removed_links ,以減少變慢的編輯。 這遵守MediaWiki的外部連結規則 。 添加到陣列中的連結都是唯一的。 更改連結將計為1個添加和1個移除連結。
|
新页面的wikitext(已预保存转换)($1) | new_pst |
字符串 | This variable can be very large. |
解析新修订版本的HTML源代码($1) | new_html |
字符串 | 這個變數可能非常大。 盡可能考慮使用added_lines 來提高性能。
|
新页面文本(不含标记)($1) | new_text |
字符串 | 這個變數可能非常大。 盡可能考慮使用added_lines 來提高性能。
|
old_html |
因效能原因而被停用。 | ||
old_text |
因效能原因而被停用。 | ||
自上次编辑页面以来的时间(以秒为单位)($1) | page_last_edit_age |
整数或null |
null when the page does not exist
|
文件内容的SHA1哈希值($1) | file_sha1 |
字符串 | [2] |
文件大小(以字节为单位)($1) | file_size |
整数 | 檔案大小,單位為位元組[2] |
文件宽度(以像素为单位)($1) | file_width |
整数 | 寬度,單位為像素[2] |
文件高度(以像素为单位)($1) | file_height |
整数 | 高度,單位為像素[2] |
文件每个颜色通道的位数($1) | file_bits_per_channel |
整数 | 每個顏色通道的位元數[2] |
文件的MIME类型($1) | file_mime |
字符串 | 檔案MIME類型。[2] |
文件的媒体类型($1) | file_mediatype |
字符串 | 檔案媒體類型。[8][2] |
移动目标页面的页面ID($1) | moved_to_articleid |
整数 | (已弃用) 請使用moved_to_id 。
|
移动目标页面的页面ID($1) | moved_to_id |
整数 | |
移动目标页面的标题($1) | moved_to_text |
字符串 | (已弃用) 請使用moved_to_title 。
|
移动目标页面的标题($1) | moved_to_title |
字符串 | |
移动目标页面的完整标题($1) | moved_to_prefixedtext |
字符串 | (已弃用) 請使用moved_to_prefixedtitle 。
|
移动目标页面的完整标题($1) | moved_to_prefixedtitle |
字符串 | |
移动目标页面的命名空间($1) | moved_to_namespace |
整数 | |
移动目标页面的时间(秒)($1) | moved_to_age |
整数 | |
自上次移动目标页面编辑以来的时间(以秒为单位)($1) | moved_to_last_edit_age
|
integer or null |
null when the target page does not exist
|
移动目标页面的编辑保护等级($1) | moved_to_restrictions_edit |
字符串数组 | 与page_restrictions_edit 相同,但对于要移动的目标。
|
移动目标页面的移动保护等级($1) | moved_to_restrictions_move |
字符串数组 | 与page_restrictions_move 相同,但对于要移动的目标。
|
移动目标文件的上传保护($1) | moved_to_restrictions_upload |
字符串数组 | 与page_restrictions_upload 相同,但对于要移动的目标。
|
创建移动目标页面的保护($1) | moved_to_restrictions_create |
字符串数组 | 与page_restrictions_create 相同,但对于要移动的目标。
|
最近十位对移动目标页面有贡献的用户($1) | moved_to_recent_contributors |
字符串数组 | 与page_recent_contributors 相同,但对于要移动的目标。
|
第一个为移动目标页面做出贡献的用户($1) | moved_to_first_contributor |
字符串 | 与page_first_contributor 相同,但对于要移动的目标。
|
移动源页面的命名空间($1) | moved_from_namespace |
整数 | |
移动源页面的标题($1) | moved_from_text |
字符串 | (已弃用) 請使用moved_from_title 。
|
移动源页面的标题($1) | moved_from_title |
字符串 | |
移动源页面的完整标题($1) | moved_from_prefixedtext |
字符串 | (已弃用) 請使用moved_from_prefixedtitle 。
|
移动源页面的完整标题($1) | moved_from_prefixedtitle |
字符串 | |
移动源页面的页面ID($1) | moved_from_articleid |
整数 | (已弃用) 請使用moved_from_id 。
|
移动源页面的页面ID($1) | moved_from_id |
整数 | |
移动源页面年龄(秒)($1) | moved_from_age |
整数 | |
自上次移动源页面编辑以来的时间(以秒为单位)($1) | moved_from_last_edit_age |
整数 | |
移动来源页面的编辑保护等级($1) | moved_from_restrictions_edit |
字符串数组 | 与page_restrictions_edit 相同,但对于要移动的页面。
|
移动来源页面的移动保护等级($1) | moved_from_restrictions_move |
字符串数组 | 与page_restrictions_move 相同,但对于要移动的页面。
|
上传移动源文件的保护($1) | moved_from_restrictions_upload |
字符串数组 | 与page_restrictions_upload 相同,但对于要移动的页面。
|
创建移动源页面的保护($1) | moved_from_restrictions_create |
字符串数组 | 与page_restrictions_create 相同,但对于要移动的页面。
|
对移动源页面做出贡献的最后十位用户($1) | moved_from_recent_contributors |
字符串数组 | 与page_recent_contributors 相同,但对于要移动的页面。
|
第一个为移动源页面做出贡献的用户($1) | moved_from_first_contributor |
字符串 | 与page_first_contributor 相同,但对于要移动的页面。
|
创建账号时的账号名称($1) | accountname |
字符串 | |
舊版本的內容模型 | old_content_model
|
字符串 | 參見Help:更改内容模型 有關更改內容模型的資料 |
新版本的內容模型 | new_content_model
|
字符串 | 參見Help:更改内容模型 有關更改內容模型的資料 |
受保护变量
变量可被视为受保护。例如,在启用了临时账号的wiki上,IP被视为PII,必须限制对它们的访问。
受保护变量和使用它们的过滤器仅能由持有abusefilter-access-protected-vars
权限的维护者访问。
使用受保护变量也会将过滤器标记为受保护。
即便过滤器不再主动使用受保护的变量,也无法取消对它的保护,因为其历史记录仍然可用。
Logs generated by protected filters can only be viewed by users with the abusefilter-protected-vars-log
right.
默认的受保护变量在extension.json
中的AbuseFilterProtectedVariables
中定义。
user_unnamed_ip
is null
when examining past edits.描述 | 名称 | 数据类型 | 备注 |
---|---|---|---|
用户账号的IP(仅适用于已注销用户和临时账户)($1) | user_unnamed_ip
|
字符串 | 匿名用户或临时账号的用户IP 注册用户返回
null 。 |
來自其他擴充功能的變數
描述 | 名称 | 資料型態 | 數值 | 由誰加入 |
---|---|---|---|---|
用户所属的全域用户组($1) | global_user_groups
|
数组 | 中央认证 | |
用户的全域编辑数($1) | global_user_editcount
|
整数 | 中央认证 | |
用户账号创建后所属的全域用户组($1) | global_account_groups
|
数组 | 仅当action 为createaccount (其总为空)或autocreateaccount 时可用。
|
中央认证 |
用户账号创建后的全域编辑数($1) | global_account_editcount
|
整数 | 仅当action 为createaccount (其总为零)或autocreateaccount 时可用。
|
中央认证 |
用于执行此更改的OAuth消费方($1) | oauth_consumer
|
整数 | 开放授权 | |
结构式讨论版块的页面ID($1) | board_articleid
|
整数 | (已弃用) 請使用board_id 。
|
结构式讨论 |
结构式讨论版块的页面ID($1) | board_id
|
整数 | 结构式讨论 | |
结构式讨论版块的命名空间($1) | board_namespace
|
整数 | 參見命名空間索引 | 结构式讨论 |
结构式讨论版块的标题(不包括命名空间)($1) | board_text
|
字符串 | (已弃用) 請使用board_title 。
|
结构式讨论 |
结构式讨论版块的标题(不包括命名空间)($1) | board_title
|
字符串 | 结构式讨论 | |
结构式讨论版块的完整标题($1) | board_prefixedtext
|
字符串 | (已弃用) 請使用board_prefixedtitle 。
|
结构式讨论 |
结构式讨论版块的完整标题($1) | board_prefixedtitle
|
字符串 | 结构式讨论 | |
翻译单元的原始文本 | translate_source_text
|
字符串 | 翻译 | |
翻译目标语言 | translate_target_language
|
字符串 | 语言代码,如英语的为en 。
|
翻译 |
此更改是否通过Tor出口节点做出($1) | tor_exit_node
|
布尔值 | 如果動作來自tor出口節點,則為true。 | Tor封鎖 |
用户是否通过移动版界面编辑($1) | user_mobile
|
布尔值 | 行動版使用者為true,否則為false。 | 移动版前端 |
用户是否正使用移动应用进行编辑($1) | user_app
|
布尔值 | 如果使用者透過行動版應用程式進行編輯,則為true,否則為false。 | MobileApp |
頁面瀏覽數[1] | article_views
|
整数 | (已弃用) 請使用page_views 。
|
HitCounters |
頁面瀏覽數[2] | page_views
|
整数 | 頁面瀏覽量 | HitCounters |
來源頁面瀏覽數[3] | moved_from_views
|
整数 | 來源頁面的頁面瀏覽量 | HitCounters |
目標頁面瀏覽數[4] | moved_to_views
|
整数 | 目標頁面的頁面瀏覽量 | HitCounters |
IP位址是否使用stopforumspam.com列表來封鎖[5] | sfs_blocked
|
布尔值 | IP位址是否使用stopforumspam.com列表來封鎖 | StopForumSpam |
注意事項
當action='move'
,只有summary
、action
、timestamp
和user_*
變數可用。
page_*
變數仍然可用,但其前綴已被取代為moved_from_
和moved_to_
,以分別表示頁面的原本名稱和目標名稱的值。
例如moved_from_title
和moved_to_title
,而不是page_title
。
自MediaWiki 1.28(gerrit:295254)起,action='upload'
僅用於發佈上傳檔案時,不再用於上傳至stash時。
新加入的action='stashupload'
用於所有上傳行為,包括上傳至stash。
This behaves like action='upload'
used to, and only provides file metadata variables (file_*
).
Variables related to the page edit, including summary
, new_wikitext
and several others, are now available for action='upload'
.
For every file upload, filters may be called with action='stashupload'
(for uploads to stash), and are always called with action='upload'
; they are not called with action='edit'
.
Filter authors should use action='stashupload' | action='upload'
in filter code when a file can be checked based only on the file contents – for example, to reject low-resolution files – and action='upload'
only when the wikitext parts of the edit need to be examined too – for example, to reject files with no description.
This allows tools that separate uploading the file and publishing the file (e.g. 上傳精靈 or upload dialog ) to inform the user of the failure before they spend the time filling in the upload details.
效能
如同前面的記載,某些變數可能使速度變得非常慢。
在编写过滤器时,请记住条件限制不是衡量过滤器性能高下的好指标。
例如,像 *_recent_contributors
或 *_links
这样的变量始终需要执行数据库查询,而 *_pst
变量将必须执行文本解析,这又是一个繁重的操作;所有这些变量都应该非常非常小心地使用。
例如,在意大利语维基百科上已经观察到,有135个启用的过滤器并平均使用450个条件,过滤器执行时间约为500毫秒,峰值达到15秒。
从单个过滤器中删除 added_links
变量,并在另一个过滤器将使用 added_lines_pst
的情况减半,则平均执行时间为50毫秒。
進一步來說:
- 仅当需要高准确性,并且在其他变量(例如
added_lines
)中检查"http://..."将会导致严重误判时,使用_links
变量。 - 仅当您确实确定非PST变量还不够时,使用
_pst
变量。 您也可以有条件地决定检查哪个变量:例如,如果您要检查一个签名,请首先检查added_lines
是否包含~~~
;
通常,在处理这些变量时,使用更多条件总是比计算繁重的变量来得好。 为了实现这一点,始终将繁重的变量作为最后条件。 最后,请注意,只要为给定过滤器计算了一个变量,便会保存该变量,任何其他过滤器都能够立即检索它。 这意味着一但有一个过滤器计算了这个变量,和数十个过滤器使用它的消耗基本相同。
關鍵字
常用功能中通常會包含以下特殊關鍵字:
like
(或matches
)— 如果左字符串能够匹配右字串指定的萬用字元,则傳回真值True。in
— 如果左字串包含右字串,则傳回真值True。 注意: 空字串不被包含在任何其他字串,亦不包含任何其他字串(甚至不包含空字串本身)。contains
類似in
,但左右運算子交換位置。 注意: 空字串不被包含在任何其他字串,亦不包含任何其他字串(甚至不包含空字串本身)。rlike
(或regex
)和irlike
— 如果左字串能够匹配右字串指定的正規表示式,则傳回真值True(irlike
不區分大小寫)。if ... then ... end
if ... then ... else ... end
... ? ... : ...
true
,false
,null
範例
代码 | 结果 | 備註 |
---|---|---|
"1234" like "12?4"
|
True | |
"1234" like "12*"
|
True | |
"foo" in "foobar"
|
True | |
"foobar" contains "foo"
|
True | |
"o" in ["foo", "bar"]
|
True | 由於(陣列被)轉換為字串 |
"foo" regex "\w+"
|
True | |
"a\b" regex "a\\\\b"
|
True | 比對跳脫字元(半形反斜線)本身時,你需要使用四個反斜線或兩個\x5C 。 (兩個都能運作。)
|
"a\b" regex "a\x5C\x5Cb"
|
True |
函式
为了简化一些常见的操作,防滥用过滤器提供了一系列内建的函式。
它们具有相同的格式functionName( arg1, arg2, arg3 )
,并且可以放置在常數或變數的位置使用。
它的参数可以是常數,可以是變數,亦可以是别的函式。
函式名稱 | 描述 |
---|---|
lcase |
将第一个参数转换为小写字母并回傳之。 |
ucase |
将第一个参数转换为大写字母并回傳之。 |
length |
回傳第一个字串参数长度。 如果參數是陣列,將回傳元素個數。 |
string |
转换为字串資料類型。 如果參數是陣列,使用換行字元來串接。 |
int |
转换为整数資料類型。 |
float |
转换为浮點數資料類型。 |
bool |
转换为布林資料類型。 |
norm |
相等於rmwhitespace(rmspecials(rmdoubles(ccnorm(arg1)))) 。
|
ccnorm
|
正規化参数中的易混淆/相近字元,并以标准形式回傳之。 字元與取代方式的清單可在git找到,例如ccnorm( "Eeèéëēĕėęě3ƐƷ" ) === "EEEEEEEEEEEEE" 。[9] 此函式的輸出文字總是大寫。 While not expensive, this function isn't cheap either, and could slow a filter down if called many times.
|
ccnorm_contains_any
|
正規化所有参数中的易混淆/相近字元,並檢查第一個字串的內容是否包含之後字串的任何一個,若有包含則回傳true(參數之數量沒有上限,使用OR邏輯判斷)。 字元與取代方式的清單可在git找到 由于使用了ccnorm ,如果传递的参数过多,该函数的运行速度可能会变慢。
|
ccnorm_contains_all
|
正規化所有参数中的易混淆/相近字元,並檢查第一個字串的內容是否包含之後的全部字串,若有包含則回傳true(參數之數量沒有上限,使用AND邏輯判斷)。 字元與取代方式的清單可在git找到。 由于使用了ccnorm ,如果传递的参数过多,该函数的运行速度可能会变慢。
|
specialratio |
回傳参数中非字母字元數量除以所有字元數量的值。 |
rmspecials |
移除参数中特殊字元,并回傳结果。 但不移除空白。 (相等於s/[^\p{L}\p{N}\s]//g。) |
rmdoubles |
移除参数中重复的字元,并回傳结果。 |
rmwhitespace |
移除空白(空格、製表字元、换行符)。 |
count |
回傳搜尋項目(第一个字串)在第二个字串中出现的次数。 如果只给出一个参数,则使用半形逗号分割,并回傳分割后片段的个数。 |
rcount
|
与count 类似,但搜尋項目改用正規表示式。 可在正規表示式中以(?i)為開頭來取消區別大小寫。 請注意,使用此函式搜尋純字串時的速度可能比count [10]慢50倍,因此請盡可能使用count [11]。
|
get_matches
|
MW 1.31+ 取得正規表達式needle(第一個字串)在haystack(第二個字串)中的匹配項目。 回傳一個陣列,第0項為完整匹配,第[n] 個項為此匹配needle中第n個匹配組。 可在正規表示式中以「(?i)」為開頭來啟用不區別大小寫。 如果匹配群組沒有匹配,則在陣列中的位置將為「false」。
|
ip_in_range |
若使用者IP(第一个字串)与指定IP段(第二个字串,可以使用CIDR塊、明確以「1.1.1.1-2.2.2.2」表示、或單個IP)匹配,则回傳true。 僅對匿名用戶有用。 支援IPv4和IPv6位址。 |
ip_in_ranges |
若使用者IP(第一个字串)与任一個指定IP段(参数数量無上限,使用邏輯OR模式,可以使用CIDR塊、明確以「1.1.1.1-2.2.2.2」表示,或單個IP)匹配,则回傳true 。 僅對匿名用戶有用。 支援IPv4和IPv6位址。
|
contains_any |
若第一个字串包含任一個之后参数内的字串(参数数量無上限,使用邏輯OR模式),则回傳true。 如果第一個參數是一個陣列,它將被轉換為字串。 |
contains_all |
若第一个字串包含每一個之后参数内的字串(参数数量無上限,使用邏輯AND模式),则回傳true。 如果第一個參數是一個陣列,它將被轉換為字串。 |
equals_to_any |
如果第一個參數與接下來的任何一個(無限量參數)參數相等(=== )則回傳true。 基本上,equals_to_any(a, b, c) 和a===b | a===c 相同,但更加緊湊且節省條件數。
|
substr |
返回第一個字符串的一部分,從第二個參數值的位置開始(從0開始),以第三個參數值作為最大長度(可選)。 |
strlen |
与length 相同。
|
strpos
|
回傳第一次匹配(第二个字串)位于栈(第一个字串)的位置,以第三個參數的值起算(選用,預設值為0)。 当匹配發生在栈的开头时,该函式会回傳0,所以可能被其他比較運算子判斷为false。 更好的方法是使用=== 或!== 以检测是否发现。 Differently from PHP's strpos(), which returns false when the needle is not found, this function returns -1 when the needle is not found.
|
str_replace |
用替换字符串取代所有匹配的搜索字符串。 该函式 有3个参数,其依序为:進行搜尋的文字,欲搜尋之文字,取代文字。 |
str_replace_regexp |
Replaces all occurrences of the search string with the replacement string using regular expressions. The function takes 3 arguments in the following order: text to perform the search on, regular expression to match, replacement expression. |
rescape |
返回部分字元前置轉義字符"\"的參數,以便該字符串可以在正規表達式中使用,而這些字符沒有特殊含義。 |
set |
设定一个變數(第一个字串)為给定值(第二个字串),以备过滤器进一步使用。 相等语法为:name := value 。
|
set_var |
与set 相同。
|
代码 | 结果 | 備註 |
---|---|---|
length( "Wikipedia" )
|
9 | |
lcase( "WikiPedia" )
|
wikipedia | |
ccnorm( "w1k1p3d14" )
|
WIKIPEDIA | ccnorm 輸出總是大寫
|
ccnorm( "ωɨƙɩᑭƐƉ1α" )
|
WIKIPEDIA | |
ccnorm_contains_any( "w1k1p3d14", "wiKiP3D1A", "foo", "bar" )
|
true | |
ccnorm_contains_any( "w1k1p3d14", "foo", "bar", "baz" )
|
false | |
ccnorm_contains_any( "w1k1p3d14 is 4w3s0me", "bar", "baz", "some" )
|
true | |
ccnorm( "ìíîïĩїį!ľ₤ĺľḷĿ" )
|
IIIIIII!LLLLLL | |
norm( "!!ω..ɨ..ƙ..ɩ..ᑭᑭ..Ɛ.Ɖ@@1%%α!!" )
|
WIKIPEDAIA | |
norm( "F00 B@rr" )
|
FOBAR | norm 移除空白字元、特殊字元與重複字元,然後使用ccnorm
|
rmdoubles( "foobybboo" )
|
fobybo | |
specialratio( "Wikipedia!" )
|
0.1 | |
count( "foo", "foofooboofoo" )
|
3 | |
count( "foo,bar,baz" )
|
3 | |
rmspecials( "FOOBAR!!1" )
|
FOOBAR1 | |
rescape( "abc* (def)" )
|
abc\* \(def\) | |
str_replace( "foobarbaz", "bar", "-" )
|
foo-baz | |
str_replace_regexp( "foobarbaz", "(.)a(.)", "$2a$1" )
|
foorabzab | |
ip_in_range( "127.0.10.0", "127.0.0.0/12" )
|
true | |
ip_in_ranges( "127.0.10.0", "10.0.0.0/8", "127.0.0.0/12" )
|
true | |
contains_any( "foobar", "x", "y", "f" )
|
true | |
get_matches( "(foo?ba+r) is (so+ good)", "fobaaar is soooo good to eat" )
|
['fobaaar is soooo good', 'fobaaar', 'soooo good'] |
运算的顺序
运算通常是按由左至右的顺序進行的,但各运算的優先度并不相同。 當過濾器判斷某條件不符合時,會停止檢查之後的條件(由於短路求值)並移動至下一個過濾器。 運算顺序如下:
- 由半形小括號(
(
与)
)括住的内容会被作为一个独立单元首先运算出。 - 将常數/常量转换为它们所代表的資料。(如
page_namespace
變成0) - 呼叫函式 (
norm
、lcase
等) - 進行
+
和-
的一元運算(定義正值或負值,例:-1234
,+1234
) - 關鍵字 (
in
、rlike
等。) - 布林反轉 (
!x
) - 求幂 (
2**3 → 8
) - 乘法相关(乘、除、餘數)
- 加减法 (
3-2 → 1
) - 比较。 (
<
,>
,==
) - 布林运算 (
&
,|
,^
) - 三元运算符 (
... ? ... : ...
) - 赋值 (
:=
)
示例
A & B | C
等同於(A & B) | C
,不同於A & (B | C)
。 需特別留意,false & true | true
和false & false | true
的計算結果都是true
。A | B & C
等同於(A | B) & C
,不同於A | (B & C)
。 需特別留意,true | true & false
和true | false & false
的計算結果都是false
。added_lines rlike "foo" + "|bar"
有错误,应使用added_lines rlike ("foo" + "|bar")
替代。
條件計數
The condition limit is (more or less) tracking the number of comparison operators + number of function calls entered.
Further explanation on how to reduce conditions used can be found at Extension:AbuseFilter/Conditions .
排除
儘管防濫用過濾器的檢查功能會將「回退」操作標示為編輯,但防濫用過濾器不會檢查回退操作。[12]
实用链接
註釋
- ↑ 將陣列和其他型態比較必定會回傳false,除了以上的範例
- ↑ 2.0 2.1 2.2 2.3 2.4 2.5 2.6 2.7 檔案上傳(action='upload')的可用的變數只有user_*, page_*, file_sha1, file_size, file_mime, file_mediatype, file_width, file_height, file_bits_per_channel(最後五個變數在MediaWiki 1.27 gerrit:281503才被加入)。 所有的file_*變數對其他動作都不可用(包含action='edit')。
- ↑ 從MediaWiki 1.28 (gerrit:295254)起
- ↑ 已經有多個使用此變數的過濾器(12)被顯示在AbuseFilterSlow Grafana dashboard當中(需要logstash權限才能檢視)。 將此變數移動到過濾器的尾端似乎有所幫助。
- ↑ 参阅phabricator:T191722
- ↑ 自此commit起棄用,且自此起停用。
- ↑ 已經有某些使用此變數的過濾器($1)被顯示在AbuseFilterSlow Grafana dashboard當中(例;需要logstash權限才能檢視)。 例如,不要使用
"text" in edit_diff_pst
(甚至是edit_diff
),而是考慮使用"text" in added_lines & !("text" in removed_lines)
。 - ↑ See the source code for a list of types.
- ↑ 注意phab:T27619。 您可以使用Special:AbuseFilter/tools來評估
ccnorm( "your string" )
以查看轉換後的字元。 - ↑ https://3v4l.org/S6IGP
- ↑ https://3v4l.org/S6IGP
- ↑ T24713 - AF不匹配回退