本主题介绍如何在 Discourse 的 受监控词汇 功能中有效使用正则表达式(regex)。
对于托管在我们平台上的站点,这些设置是隐藏的。付费托管计划的客户可以通过
team@discourse.org联系我们的支持团队,申请在受监控词汇中使用正则表达式。
注意:此功能不适用于我们的免费托管计划。
正则表达式(regex)是定义搜索模式的强大工具。您可以在 受监控词汇 功能中使用正则表达式,以提高 Discourse 站点上词汇过滤的准确性和灵活性。
要在受监控词汇中使用正则表达式(regex),您必须首先启用
watched_words_regular_expressions站点设置。
正则表达式功能极其强大,因此也具有危险性。编写错误的正则表达式语句可能会给用户带来问题。在上线之前,请在非生产环境中测试您的正则表达式语句。
正则表达式模式示例
以下是一些常见的正则表达式模式及其用法:
不区分大小写
默认情况下,Discourse 会匹配单词的大写和小写形式。
thread
这将匹配 thread、THREAD 和 thReAd。
字符选项
使用字符选项来扩展匹配范围。
(t|7)hr(3|e)(4|a)d
这将匹配上述所有情况,以及 thr3ad、7hread 和 thr34d。
threads?\b
这将匹配 thread 和 threads,但不会匹配 threaded 或 threading。
单词边界
正则表达式模式可能会意外匹配单词的一部分。使用单词边界以避免部分匹配。
\bthreads?\b
这将匹配 thread 和 threads,但避免匹配如 threadlike 或 unthreading 等情况。
处理 Unicode 字符
标准单词边界在处理 Unicode 字符时可能会失效。请为 JavaScript 正则表达式处理不佳的字符创建边界。
gr(ü|ue)(ß|ss)e
这将匹配单词 grüße 的所有常见拼写形式,包括 gruesse 和 GRÜSSE。
假设您想屏蔽单词 Über,但不屏蔽 Übersicht。使用像 \b(ü|ue)ber\b 这样的单词边界不起作用,因为某些 JavaScript 正则表达式的单词标志无法处理 Unicode 字符。相反,您需要自己创建边界。
(?:^|\s)(ü|ue)ber\b
这将正确匹配 Über 和 ueber,但不会匹配 Übersicht 或 uebersicht。
捕获故意的字符替换
要捕获用户用数字或特殊字符替换字母的情况:
\bp[a@]ssw[o0]rd\b
这将匹配:password、p@ssword、passw0rd、p@ssw0rd,但不会匹配 mypassword 或 password123。
处理字符间带有标点符号的情况
要捕获用户通过插入标点符号来绕过过滤器的尝试:
\bs\W*p\W*a\W*m\b
这将匹配:spam、s.p.a.m、s-p-a-m,但不会匹配 s_p_a_m(下划线是单词字符)、spammy 或 myspam。
匹配多个单词变体
用于匹配可能以不同单词形式出现的短语:
\b(contact|email|reach)( us| me)?\b
这将匹配:contact、contact us、contact me、email、email us、email me、reach、reach us、reach me。
检测电子邮件模式
用于捕获通用的电子邮件地址模式:
\b[\w.%+-]+@[\w.-]+\.[a-zA-Z]{2,}\b
这将匹配:user@example.com、my.name@sub.domain.co.uk、user+tag@domain.org。
查找标签变体
用于匹配具有不同大小写或轻微变体的标签:
\#(disc[o0]urse|f[o0]rum)\b
这将匹配:#discourse、#DISCOURSE、#disc0urse、#forum、#f0rum,但不会匹配 #discourseengine 或 #forums。
检测重复模式
用于捕获可能表示垃圾内容的重复字符:
([a-zA-Z])\1{3,}
这将匹配:aaaample、helllllo、yessssss,检测任何连续重复 4 次或更多次的字母。
查找带或不带协议的 URL
\b(?:https?:\/\/)?[\w-]+(\.[\w-]+)+\b
这将匹配:example.com、sub.domain.org、https://discourse.org、http://meta.discourse.org。
避免嵌套字符类
正确:
(hold)?
这将正确匹配可选单词 “hold”。
或者,如果您需要字符选项:
[h][o0][l1][d]
这将匹配:hold、h0ld、ho1d、h01d。
错误:
[h[o0][l1]d]?
这将错误地尝试嵌套字符类,并会匹配 h、o、0、l、1 或 d 中的任意单个字符,导致匹配如 had、old 等单词。
使用括号表示可选单词
正确:
forum(s)?
这将正确匹配:forum、forums。
错误:
forum[s]?
这将匹配 “forum” 后跟一个可选的 “s”,但不必要地使用了字符类。
正确使用字符类
正确:
bad word
用于匹配短语 “bad word”。
或者,作为字符类示例:
[bB][aA][dD]
这将匹配:bad、Bad、bAd、BAD 等。
错误:
[bad word]
这将匹配 b、a、d、w、o、r 或 d 中的任意单个字符,而不是短语 “bad word”。
有效使用量词
\b[0-9]{3,5}\b
这将匹配 3 到 5 位数字:123、1234、12345,但不会匹配 12 或 123456。
对于特定的重复模式:
(spam){2,3}
这将匹配:spamspam、spamspamspam。
正确应用单词边界
无边界:
free
这将匹配:free、freedom、carefree。
带边界:
\bfree\b
这将仅匹配:free,但不会匹配 freedom 或 carefree。
正确处理 Unicode 字符
正确方法:
(?:^|\s)(ö|oe)zel\b
这将匹配:özel、oezel,即使在单词边界处包含 Unicode 字符。
错误方法:
\bözel\b
这可能无法正确处理土耳其语字符 ö。
附加信息
您可以在 https://regex101.com/ 上测试正则表达式。如果这样做,请确保将正则表达式风格切换为 ECMAScript。
在受监控词汇的替换值中,不支持正则表达式捕获组反向引用(例如替换字符串中的 \1)。替换和链接操作支持使用正则表达式进行匹配,但替换结果始终是字面字符串。