Jump to content

Extension:滥用过滤器/规则格式

From mediawiki.org
This page is a translated version of the page Extension:AbuseFilter/Rules format and the translation is 95% complete.

該規則是自定義的語言,其格式与类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_namespace145,则此值也将评估为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 < 任何數值 === truenull > 任何數值 === false
  • <=、​>= – 如果左運算元分別小於或等於/大於或等於右運算元,則回傳true。 注意:運算元會被轉換為字串,就如同在PHP發生的一樣,null <= 任何數值 === truenull >= 任何數值 === 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
小心! 小心: On wikis where temporary accounts are enabled, IPs are not returned for unregistered users. Use user_unnamed_ip instead if the IP is needed. More context is available here .
账号类型($1) user_type 字符串 用户的类型,是iptemp(如果用户使用的是临时账户 )、namedexternalunknown中的其中一种。
确认电子邮件地址的时间($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.
Edit variables are not available when examining past uploads. (T345896)
描述 名称 資料型態 備註
编辑摘要/原因($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_linesremoved_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來提高性能。
旧页面的wikitext,解析为HTML(不再使用) 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


來自其他擴充功能的變數

Most of these variables are always set to false when examinating past edits, and may not reflect their actual value at the time the edit was made. 参见T102944
描述 名称 資料型態 數值 由誰加入
用户所属的全域用户组($1) global_user_groups 数组 中央认证
用户的全域编辑数($1) global_user_editcount 整数 中央认证
用户账号创建后所属的全域用户组($1) global_account_groups 数组 仅当actioncreateaccount(其总为空)或autocreateaccount时可用。 中央认证
用户账号创建后的全域编辑数($1) global_account_editcount 整数 仅当actioncreateaccount(其总为零)或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',只有summaryactiontimestampuser_*變數可用。 page_*變數仍然可用,但其前綴已被取代為moved_from_moved_to_,以分別表示頁面的原本名稱和目標名稱的值。 例如moved_from_titlemoved_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區分大小寫)。
    • 此系統使用PCRE
    • 只有PCRE_UTF8PHP修飾字u)選項被啟用。irlikePCRE_CASELESSPCRE_UTF8選項被啟用(修飾字iu)。
  • 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']

运算的顺序

运算通常是按由左至右的顺序進行的,但各运算的優先度并不相同。 當過濾器判斷某條件不符合時,會停止檢查之後的條件(由於短路求值)並移動至下一個過濾器。 運算顺序如下:

  1. 由半形小括號(())括住的内容会被作为一个独立单元首先运算出。
  2. 将常數/常量转换为它们所代表的資料。(如page_namespace變成0)
  3. 呼叫函式 (normlcase等)
  4. 進行+-的一元運算(定義正值或負值,例:-1234+1234
  5. 關鍵字 (inrlike等。)
  6. 布林反轉 (!x)
  7. 求幂 (2**3 → 8)
  8. 乘法相关(乘、除、餘數)
  9. 加减法 (3-2 → 1)
  10. 比较。 (<, >, ==)
  11. 布林运算 (&, |, ^)
  12. 三元运算符 (... ? ... : ...)
  13. 赋值 (:=)

示例

  • A & B | C等同於(A & B) | C,不同於A & (B | C)。 需特別留意,false & true | truefalse & false | true的計算結果都是true
  • A | B & C等同於(A | B) & C,不同於A | (B & C)。 需特別留意,true | true & falsetrue | 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]

实用链接

註釋

  1. 將陣列和其他型態比較必定會回傳false,除了以上的範例
  2. 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')。
  3. 從MediaWiki 1.28 (gerrit:295254)起
  4. 已經有多個使用此變數的過濾器(12)被顯示在AbuseFilterSlow Grafana dashboard當中(需要logstash權限才能檢視)。 將此變數移動到過濾器的尾端似乎有所幫助。
  5. 参阅phabricator:T191722
  6. 此commit起棄用,且自起停用。
  7. 已經有某些使用此變數的過濾器($1)被顯示在AbuseFilterSlow Grafana dashboard當中(;需要logstash權限才能檢視)。 例如,不要使用"text" in edit_diff_pst(甚至是edit_diff),而是考慮使用"text" in added_lines & !("text" in removed_lines)
  8. See the source code for a list of types.
  9. 注意phab:T27619。 您可以使用Special:AbuseFilter/tools來評估ccnorm( "your string" )以查看轉換後的字元。
  10. https://3v4l.org/S6IGP
  11. https://3v4l.org/S6IGP
  12. T24713 - AF不匹配回退