Эта тема объясняет, как эффективно использовать регулярные выражения (regex) в функции Watched Words на Discourse.
Для сайтов на нашем хостинге эти настройки скрыты. Клиенты с платными тарифами могут обратиться в нашу службу поддержки по адресу team@discourse.org, чтобы запросить использование regex с функцией Watched Words.
Примечание: Эта функция недоступна в нашем бесплатном тарифе хостинга.
Регулярные выражения (regex) — это мощный инструмент для определения шаблонов поиска. Вы можете использовать regex в функции Watched Words, чтобы повысить точность и гибкость фильтрации слов на вашем сайте Discourse.
Чтобы использовать регулярные выражения (regex) в Watched Words, вы должны сначала включить настройку сайта watched_words_regular_expressions.
Regex чрезвычайно мощный и поэтому опасный. Неправильно написанное регулярное выражение может вызвать проблемы у ваших пользователей. Протестируйте свои regex-выражения на тестовых (не продакшн) экземплярах перед запуском в работу.
Примеры шаблонов Regex
Вот несколько распространённых шаблонов regex и способы их применения:
Регистронезависимость
По умолчанию Discourse сопоставляет как заглавные, так и строчные формы слова.
: thread
Это будет соответствовать thread, THREAD и thReAd.
Альтернативы символов
Используйте альтернативы символов, чтобы расширить поиск.
: (t|7)hr(3|e)(4|a)d
Это будет соответствовать всем вышеперечисленным случаям, а также thr3ad, 7hread и thr34d.
: threads?\b
Это будет соответствовать thread и threads, но не threaded или threading.
Границы слов
Шаблоны regex могут случайно совпадать с частями слов. Используйте границы слов, чтобы избежать частичных совпадений.
\bthreads?\b
Это соответствует thread и threads, но избегает совпадений вроде threadlike или unthreading.
Обработка символов Unicode
Стандартные границы слов могут не работать с символами Unicode. Создавайте границы для символов, которые плохо обрабатываются в JavaScript regex.
: gr(ü|ue)(ß|ss)e
Это соответствует всем распространённым написаниям слова grüße — включая gruesse и GRÜSSE.
Допустим, вы хотите заблокировать слово Über, но не Übersicht. Использование границ слов вроде \b(ü|ue)ber\b не работает, потому что некоторые флаги границ слов в JavaScript regex не обрабатывают символы 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.
Обнаружение шаблонов email-адресов
Чтобы выявлять общие шаблоны email-адресов:
\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.
Обратные ссылки на группы захвата regex (например, \1 в строках замены) не поддерживаются в значениях замены Watched Words. Действия замены и создания ссылок поддерживают regex для сопоставления, но замена всегда является буквенно-цифровой строкой.