互聯網群組建立者、管理者應當履行群組管理責任,依據法律法規、用戶協議和平台公約,規範群組網絡行為和信息發布。互聯網群組成員在參與群組信息交流時,應當遵守法律法規,文明互動、理性表達。
——《互聯網群組信息服務管理規定》
雖然幾乎沒有門檻的 Matrix 作者微信群方便了大家「頭腦風暴」,但活潑跳躍的讨論氛圍另一方面也帶來了危險。所謂「群員試探群主負責」,為了讓 Matrix 作者群遠離「炸群」,@路中南 同學常常需要第一時間空降群内維護秩序。
如何針對聊天内容每天數以百計的群聊進行管理呢?内心狂吼「太南」的同時,路中南同學心裡漸漸萌生了一個新的解決方案:
如果微信能夠針對某些敏感詞彈出提醒就好了。
分析需求,理清思路
指望微信實現這類功能雖然不太可行,好在 Android 平台足夠強大,我們完全不至于束手無策 —— 既然路中南同學想要針對性的通知服務,那我們不妨也直接從通知管理入手。
少數派曾經介紹過 通知濾盒 這款應用,它利用了 Android 上系統「讀取通知」權限,可以根據用戶設置的關鍵詞對通知進行消除和靜音處理,以避免「垃圾」通知影響使用體驗。
雖然核心理念是通知「斷舍離」,為了應對多樣的通知管理需要,通知濾盒也内建了一套基于正則表達式匹配的通知過濾功能:利用正則表達式中的多條規則對通知進行複雜匹配,查找通知内容中符合條件的關鍵字,然後對特定通知進行屏蔽。
這種正則表達式看着像是貓咪踩過鍵盤而打出的一堆亂碼,實際上我們可以将它看作是用特定符代替某一類字符、用多條規則執行查找關鍵字任務的「一句話編程」。
正則表達式的「元字符」、語法、匹配、運算等基本規則以及通知濾盒的使用方法本文不再贅述,感興趣的讀者請自行搜索學習。
具體而言,針對文章開頭提到的需求:
- 首先我們要明确通知濾盒的過濾範圍僅僅是「少數派 Matrix 作者群」,不能影響私聊和其他群組
- 其次就是通知含有敏感詞時才提醒,其他情況保持靜默
分析需求後我們可以整理出如下圖示:
而在構建正則表達式之前我們首先要知道,通知濾盒将通知的标題(android.title)和内容(android.text)看作是同一個字符串,所以我們才能夠用一句正則表達式完成匹配工作。
标題和内容解析後成為同一個字符串
正則表達式語法并不困難,正如開篇所說,它就是「一句話編程」。不過既然是編程,那肯定是需要一定的邏輯思維。我們先整理一下思路:
不過在解決路中南同學的需求時,如果按照這種思路構造正則表達式那可就錯了 —— 因為通知濾盒對通知的管理思路是「屏蔽匹配」的通知,而正則表達式的作用是「提示匹配」,兩者恰好相反。
所以我們要轉換一下思路,實際的規則應該是這樣子:
這條思路就站在了通知濾盒的角度,使其能夠過濾特定群聊、屏蔽不含敏感詞的通知、放行包含敏感詞的通知。
至此,我們現在可以開始構建真正的正則表達式了。
開始構建正則
在正則表達式中,除了已經具有特定含義的「元字符」以外,其他字符(例如字母、數字)都會匹配它們自己,因此使用群名「少數派 Matrix 作者群」來匹配它自身的字符串即可。
而對于通知内容,正則表達式并不能直接實現「不包含」匹配,不過可以利用「零寬斷言」(也叫預查、環視)語法曲線救國。在這裡,我們使用其中的「負先行斷言」語法執行「不包含敏感詞」匹配任務,即:
少數派 Matrix 作者群(?!敏感詞)// 該表達式僅作語法說明使用
該語法會匹配後面沒有「敏感詞」的「少數派 Matrix 作者群」。這就完成了嗎?當然不是,舉個例子,用該表達式分别嘗試匹配這兩個示例:
使用 regex101 測試,示例 <2> 被匹配,通知被屏蔽
如果按照原先設想,這兩個字符串都應該因為包含「敏感詞」而匹配失敗(即通知被放行),但為什麼示例 <2> 會提示匹配成功呢?原因是正則表達式有一定的運算規則,導緻該表達式隻認可「群」字後面的第一個位置沒有「敏感詞」字符(串),故匹配成功。
「群」字後第一個位置沒有匹配「不包含」語法,匹配成功,通知被屏蔽
但實際上,敏感詞可能會出現句子中的任何位置,換句話說,敏感詞的前後位置可能會出現任意字符,每個字符可能會出現零次或多次,所以我們要添加通配符「.」和限定符「*」:
少數派 Matrix 作者群(?!.*敏感詞)// 表示「敏感詞」左邊可以出現任意字符零次或多次
實際上,我們隻需要在「敏感詞」左邊添加「.*」符号即可,因為我們匹配到敏感詞就足夠了,無需關心右邊是否還有内容。
進階正則表達式
上面的正則表達式已經可以實現路中南同學的需求了,但假如路中南同學升職了,承擔起 10 個、20 個甚至更多少數派群聊的管理責任怎麼辦,難道要錄入幾十條正則表達式?
其實我們也可以利用正則表達式實現「群名包含少數派」功能。
方法一:簡單粗暴的通配符方式
與剛才的思路很相近,既然「少數派」三個字有可能出現在任意位置,那我們也使用通配符就好了。
.*少數派(?!.*敏感詞)
不過這一次,我們隻在「少數派」左邊添加通配符的理由相對燒腦一點,具體原因涉及到零寬斷言匹配順序以及「貪婪」模式,感興趣的讀者可以自行搜索學習。
方法二:需要動腦筋的零寬斷言
零寬斷言語法也可以實現「包含」匹配,當然可以實現。我們在這裡使用「正先行斷言」:
(?=少數派)(?!.*敏感詞)// 注意使用括号進行分組和優先級分配
該表達式可以匹配到右邊不包含「敏感詞」的「少數派」字符串。
方式二匹配到了空字符(下圖紅色豎線處)
細化進階用法
實際生活中,路中南同學需要關注的敏感詞可不止一個,我們可以使用「|」符号來實現「或」的功能:
.*少數派(?!.*(敏感詞A|敏感詞B|敏感詞C))(?=少數派)(?!.*(敏感詞A|敏感詞B|敏感詞C))// 注意使用括号進行分組和優先級分配// 該方式未進行嚴格匹配,因此會匹配到空字符
在正則表達式中,通配符「.」并不會匹配換行符,這有可能導緻正則失效。為了避免無法匹配通知裡存在換行符而敏感詞恰好出現在換行符之後的情況,我們也可以使用「或」操作,将「.*」補充為「.*|\n」,這樣換行符就能被識别到。如果你已經了解了正則表達式,你還可以利用分組和調用的語法,讓正則表達式更加簡潔。
除此之外,使用位置限定符「^」、「$」并根據語法與其他元符号組合,實現開頭、結尾或整個字符串的嚴格匹配,能夠讓正則表達式及其返回結果更加規範、可讀性更強:
^.*少數派(?!.*(敏感詞A|敏感詞B|敏感詞C)).*$^.*(?=少數派)(?!.*(敏感詞A|敏感詞B|敏感詞C)).*$// 此時通配符是必要的,具體原因可以參考位置限定符的作用
相對完善的正則表達式
不過在解決路中南同學的需求時,我們隻需要表達式返回「true」或者「false」給通知濾盒以屏蔽或放行通知,不要求表達式返回匹配内容,因此新手可以不做嚴格匹配。當然我們更建議大家養成良好的書寫習慣,盡可能完善代碼。
關于匹配成功卻看不到返回結果:在正則表達式的世界裡,每一個字符前面都有一個用來表示位置的「空字符」(是什麼都沒有而不是空格),某些表達式(例如沒有要求嚴格匹配)會匹配到這些空字符。因此我們在測試上述表達式時,可能會提示匹配成功,卻看不到匹配了什麼字符。
更高級卻更簡單的 JSON
除了正則表達式,通知濾盒還提供了 JSON 語法匹配。雖然 JSON 匹配在 App 裡被稱為「高級匹配功能」,不過借助幫助文檔中給出的 JSON 模闆,我們實現路中南同學的需求反而更加輕松 —— 因為我們不用再思考如何将多個匹配規則嵌套成一條表達式了。
通知濾盒的 JSON 模闆大緻分為三部分:匹配模式、匹配字段、正則表達式。具體使用方法可以參考通知濾盒幫助文檔。簡言之,我們在通知濾盒中找到需要匹配的字段,并填充針對該字段的正則表達式,同時在開頭聲明這些表達式的與、或、非關系就可以了。
{ "match": "ALL", "node": [ { "field": "android.title", "regex": "少數派" }, { "field": "android.text", "regex": "^(?!.*(敏感詞A|敏感詞B|敏感詞C)).*$" // 針對本文案例,此處需要嚴格匹配 } ]}
小結
這種方式仍有一定弊端,那就是如果群聊内容過長(例如 Matrix 群讨論),微信通知可能會折疊後面的内容,此時通知濾盒便無能為力了。不過即便如此,這種方法仍然能提醒路中南同學及時維護日常群聊的秩序。
借助開放的 Android 平台,通知濾盒可以實現非常強大的通知管理功能,尤其是配合正則表達式和 JSON 後可以針對不同類型、不同内容的通知進行細化管理,除了剛才說的對關鍵字進行提醒,也可以屏蔽好友砍價、微商廣告,或是像幫助文件中那樣屏蔽播放控件廣告等等。其實我們很多需求不必苦苦等待着更「傻瓜」的方式出現,借助現有工具,動動腦筋,說不定你就是下一個開發者。
你可以在 酷安 和 Play 商店 下載通知濾盒。
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!