互聯網羣組建立者、管理者應當履行羣組管理責任,依據法律法規、用戶協議和平臺公約,規範羣組網絡行爲和信息發佈。互聯網羣組成員在參與羣組信息交流時,應當遵守法律法規,文明互動、理性表達。

——《互聯網羣組信息服務管理規定》

雖然幾乎沒有門檻的 Matrix 作者微信羣方便了大家「頭腦風暴」,但活潑跳躍的討論氛圍另一方面也帶來了危險。所謂「羣員試探羣主負責」,爲了讓 Matrix 作者羣遠離「炸羣」,@路中南同學常常需要第一時間空降羣內維護秩序。

如何針對聊天內容每天數以百計的羣聊進行管理呢?內心狂吼「太南」的同時,路中南同學心裏漸漸萌生了一個新的解決方案:

如果微信能夠針對某些敏感詞彈出提醒就好了。

分析需求,理清思路

指望微信實現這類功能雖然不太可行,好在 Android 平臺足夠強大,我們完全不至於束手無策——既然路中南同學想要針對性的通知服務,那我們不妨也直接從通知管理入手。

少數派曾經介紹過通知濾盒 這款應用,它利用了 Android 上系統「讀取通知」權限,可以根據用戶設置的關鍵詞對通知進行消除和靜音處理,以避免「垃圾」通知影響使用體驗。

雖然核心理念是通知「斷舍離」,爲了應對多樣的通知管理需要,通知濾盒也內建了一套基於正則表達式匹配的通知過濾功能:利用正則表達式中的多條規則對通知進行復雜匹配,查找通知內容中符合條件的關鍵字,然後對特定通知進行屏蔽。

這種正則表達式看着像是貓咪踩過鍵盤而打出的一堆亂碼,實際上我們可以將它看作是用特定符代替某一類字符、用多條規則執行查找關鍵字任務的「一句話編程」。

正則表達式的「元字符」、語法、匹配、運算等基本規則以及通知濾盒的使用方法本文不再贅述,感興趣的讀者請自行搜索學習。

具體而言,針對文章開頭提到的需求:

  • 首先我們要明確通知濾盒的 過濾範圍 僅僅是「少數派 Matrix 作者羣」,不能影響私聊和其他羣組
  • 其次就是通知含有敏感詞時才提醒,其他情況保持靜默

分析需求後我們可以整理出如下圖示:

而在構建正則表達式之前我們首先要知道,通知濾盒將通知的標題(android.title)和內容(android.text)看作是 同一個字符串 ,所以我們才能夠用一句正則表達式完成匹配工作。

標題和內容解析後成爲同一個字符串

正則表達式語法並不困難,正如開篇所說,它就是「一句話編程」。不過既然是編程,那肯定是需要一定的邏輯思維。我們先整理一下思路:

不過在解決路中南同學的需求時,如果按照這種思路構造正則表達式那可就錯了——因爲通知濾盒對通知的管理思路是「屏蔽匹配」的通知,而正則表達式的作用是「提示匹配」, 兩者恰好相反

所以我們要轉換一下思路,實際的規則應該是這樣子:

這條思路就站在了通知濾盒的角度,使其能夠 過濾特定羣聊、屏蔽不含敏感詞的通知、放行包含敏感詞的通知

至此,我們現在可以開始構建真正的正則表達式了。

開始構建正則

在正則表達式中,除了已經具有特定含義的「元字符」以外,其他字符(例如字母、數字)都會匹配它們自己,因此使用羣名 「少數派 Matrix 作者羣」 來匹配它自身的字符串即可。

而對於通知內容,正則表達式並不能直接實現「不包含」匹配,不過可以利用 「零寬斷言」 (也叫預查、環視)語法曲線救國。在這裏,我們使用其中的 「負先行斷言」 語法執行「不包含敏感詞」匹配任務,即:

<code>少數派 Matrix 作者羣(?!敏感詞)</code><code>// 該表達式僅作語法說明使用</code>

該語法會匹配後面沒有「敏感詞」的「少數派 Matrix 作者羣」。這就完成了嗎?當然不是,舉個例子,用該表達式分別嘗試匹配這兩個示例:

使用 regex101 測試,示例 <2> 被匹配,通知被屏蔽

如果按照原先設想,這兩個字符串都應該因爲包含「敏感詞」而匹配失敗(即通知被放行),但爲什麼示例 <2> 會提示匹配成功呢?原因是正則表達式有一定的 運算規則 ,導致該表達式 只認可「羣」字後面的第一個位置 沒有「敏感詞」字符(串),故匹配成功。

「羣」字後第一個位置沒有匹配「不包含」語法,匹配成功,通知被屏蔽

但實際上,敏感詞可能會出現句子中的任何位置,換句話說,敏感詞的前後位置可能會出現 任意字符 ,每個字符可能會出現 零次或多次 ,所以我們要添加通配符 「.」 和限定符 「*」

<code>少數派 Matrix 作者羣(?!.*敏感詞)</code><code>// 表示「敏感詞」左邊可以出現任意字符零次或多次</code>

實際上,我們只需要在「敏感詞」左邊添加「.*」符號即可,因爲我們匹配到敏感詞就足夠了,無需關心右邊是否還有內容。

進階正則表達式

上面的正則表達式已經可以實現路中南同學的需求了,但假如路中南同學升職了,承擔起 10 個、20 個甚至更多少數派羣聊的管理責任怎麼辦,難道要錄入幾十條正則表達式?

其實我們也可以利用正則表達式實現「羣名包含少數派」功能。

方法一:簡單粗暴的通配符方式

與剛纔的思路很相近,既然「少數派」三個字有可能出現在任意位置,那我們也使用通配符就好了。

.*少數派(?!.*敏感詞)

不過這一次,我們只在「少數派」左邊添加通配符的理由相對燒腦一點,具體原因涉及到零寬斷言匹配順序以及「貪婪」模式,感興趣的讀者可以自行搜索學習。

方法二:需要動腦筋的零寬斷言

零寬斷言語法也可以實現「包含」匹配,當然可以實現。我們在這裏使用 「正先行斷言」

<code>(?=少數派)(?!.*敏感詞)</code><code>// 注意使用括號進行分組和優先級分配</code>

該表達式可以匹配到右邊不包含「敏感詞」的「少數派」字符串。

方式二匹配到了空字符(下圖紅色豎線處)

細化進階用法

實際生活中,路中南同學需要關注的敏感詞可不止一個,我們可以使用 「|」 符號來實現 「或」 的功能:

<code>.*少數派(?!.*(敏感詞A|敏感詞B|敏感詞C))</code><code>(?=少數派)(?!.*(敏感詞A|敏感詞B|敏感詞C))</code><code>// 注意使用括號進行分組和優先級分配</code><code>// 該方式未進行嚴格匹配,因此會匹配到空字符</code>

在正則表達式中,通配符 「.」不會匹配換行符 ,這有可能導致正則失效。爲了避免無法匹配通知裏存在換行符而敏感詞恰好出現在換行符之後的情況,我們也可以使用「或」操作,將「.*」補充爲「.*|\n」,這樣換行符就能被識別到。如果你已經瞭解了正則表達式,你還可以利用分組和調用的語法,讓正則表達式更加簡潔。

除此之外,使用位置限定符 「^」「$」 並根據語法與其他元符號組合,實現開頭、結尾或整個字符串的嚴格匹配,能夠讓正則表達式及其返回結果更加規範、可讀性更強:

<code>^.*少數派(?!.*(敏感詞A|敏感詞B|敏感詞C)).*$</code><code>^.*(?=少數派)(?!.*(敏感詞A|敏感詞B|敏感詞C)).*$</code><code>// 此時通配符是必要的,具體原因可以參考位置限定符的作用</code>
相對完善的正則表達式

不過在解決路中南同學的需求時,我們只需要表達式返回「true」或者「false」給通知濾盒以屏蔽或放行通知,不要求表達式返回匹配內容,因此新手可以不做嚴格匹配。當然我們更建議大家養成良好的書寫習慣,儘可能完善代碼。

關於 匹配成功卻看不到返回結果 :在正則表達式的世界裏,每一個字符前面都有一個用來表示位置的「空字符」(是什麼都沒有而不是空格),某些表達式(例如沒有要求嚴格匹配)會匹配到這些空字符。因此我們在測試上述表達式時,可能會提示匹配成功,卻看不到匹配了什麼字符。

更高級卻更簡單的 JSON

除了正則表達式,通知濾盒還提供了 JSON 語法匹配 。雖然 JSON 匹配在 App 裏被稱爲「高級匹配功能」,不過藉助幫助文檔中給出的 JSON 模板,我們實現路中南同學的需求反而更加輕鬆——因爲我們不用再思考如何將多個匹配規則嵌套成一條表達式了。

通知濾盒的 JSON 模板大致分爲三部分:匹配模式、匹配字段、正則表達式。具體使用方法可以參考 通知濾盒幫助文檔 。簡言之,我們在通知濾盒中找到需要匹配的字段,並填充針對該字段的正則表達式,同時在開頭聲明這些表達式的與、或、非關係就可以了。

<code>{</code><code>  "match": "ALL",</code><code>  "node": [</code><code>    {</code><code>      "field": "android.title",</code><code>      "regex": "少數派"</code><code>    },</code><code>    {</code><code>      "field": "android.text",</code><code>      "regex": "^(?!.*(敏感詞A|敏感詞B|敏感詞C)).*$"</code><code>       // 針對本文案例,此處需要嚴格匹配</code><code>    }</code><code>    ]</code><code>}</code>

小結

這種方式仍有一定弊端,那就是如果羣聊內容過長(例如 Matrix 羣討論),微信通知可能會摺疊後面的內容,此時通知濾盒便無能爲力了。不過即便如此,這種方法仍然能提醒路中南同學及時維護日常羣聊的秩序。

藉助開放的 Android 平臺,通知濾盒可以實現非常強大的通知管理功能,尤其是配合正則表達式和 JSON 後可以針對不同類型、不同內容的通知進行細化管理,除了剛纔說的對關鍵字進行提醒,也可以屏蔽好友砍價、微商廣告,或是像幫助文件中那樣屏蔽播放控件廣告等等。其實我們很多需求不必苦苦等待着更「傻瓜」的方式出現,藉助現有工具,動動腦筋,說不定你就是下一個開發者。

你可以在 酷安 和  Play 商店 下載通知濾盒。

本文所述方法和規則可能存在紕漏,如果你有更完善的解決方法,歡迎在評論區分享。

關聯閱讀: App+1 | 解決 Android 通知管理難題,用正則表達式過濾無關推送:通知濾盒

> 下載少數派客戶端、關注少數派公衆號,發現更多實用 Android 應用玩法 :eyes:

相關文章