Skip to content

Instantly share code, notes, and snippets.

@imDaniX
Last active April 16, 2024 18:28
Show Gist options
  • Save imDaniX/8449f40655fcc1b92ae8d756cbca1264 to your computer and use it in GitHub Desktop.
Save imDaniX/8449f40655fcc1b92ae8d756cbca1264 to your computer and use it in GitHub Desktop.
Мат фильтр | Регулярка антимат

Регулярное выражение для нахождения русского мата в тексте. Использовать следует только для первичной модерации, ибо обходится нажатием в одну клавишу. Если вам требуется полноценный фильтра мата, советую прибегнуть к программному пути создания такового, найти третье API, или просто остановиться на ручной модерации.

Выражение писалось в первую очередь с оглядкой на регулярки Java - для других языков может потребоваться адаптация.

Основа регулярного выражения

\b(
((у|[нз]а|(хитро|не)?вз?[ыьъ]|с[ьъ]|(и|ра)[зс]ъ?|(о[тб]|п[оа]д)[ьъ]?|(.\B)+?[оаеи-])-?)?(
  [её](б(?!о[рй]|рач)|п[уа](ц|тс))|
  и[пб][ае][тцд][ьъ]
).*?|

((н[иеа]|ра[зс]|[зд]?[ао](т|дн[оа])?|с(м[еи])?|а[пб]ч)-?)?ху([яйиеёю]|л+и(?!ган)).*?|

бл([эя]|еа?)([дт][ьъ]?)?|

\S*?(
  п(
    [иеё]зд|
    ид[аое]?р|
    ед(р(?!о)|[аое]р|ик)
  )|
  бля([дбц]|тс)|
  [ое]ху[яйиеё]|
  хуйн|
  охую
).*?|

(о[тб]?|про|на|вы)?м(
  анд([ауеыи](л(и[сзщ])?[ауеиы])?|ой|[ао]в.*?|юк(ов|[ауи])?|е[нт]ь|ища)|
  уд([яаиое].+?|е?н([ьюия]|ей))|
  [ао]л[ао]ф[ьъ]([яиюе]|[еёо]й)
)|

елд[ауые].*?|
ля[тд]ь|
([нз]а|по)х
)\b

Пояснение

Для удобства чтения маты разделены строками и пробелами. Некоторые маты обрабатываются повторно по-разному для отловки вариаций. Если ваш обработчик регулярных выражений не поддерживает подобное раздельное написание, просто соедините всё в одну непрерывную строку; если ваш текстовый редактор может заменять по регулярке, то достаточно будет заменить [\n\s] на ничто.

Граница матерных слов определяется с помощью конструкции \b(...)\b. Для правильной работы также требуются флаги работы с юникодом u и игнорирования регистра i. Но, например, в JavaScript якорь \b с русским языком попросту не работает даже с флагом юникода - придется извертываться.

Дополнительно

Далее, рекомендую добавить ?: к каждой группе, чтобы движок не готовил результаты с ними - на regex101 скорость обработки на Java увеличивается в 2-3 раза; сделать это можно в редакторе текста заменой по регулке \((?!\?) на (?:.

Раньше я занимался вариантом выражения с транскриптом, но его ведение тратит слишком много времени, а обходится оно всё равно очень тривиально. Эту вариацию регулярки для Java можно найти в истории правок этого gist'а, либо напрямую здесь - для других языков можете поискать обсуждения в комментариях.

Готовые выражения

Ниже можно увидеть готовые выражения, которые я готовлю и обновляю с каждым изменеием.

  • Java. Установлен флаг x, который игнорирует пробельные символы в выражении, что позволяет его оставить многострочным. Также доступен однострочный вариант.
  • JavaScript. Флаги iu нужно проставить самостоятельно, например /регулярное выражение/iu. Начальный и конечный якори \b заменены на (?<![а-яё]) и (?![а-яё]) соответственно; выражение .\B заменено на \S(?=[а-яё]).
  • Python. Применены те же меры, что в варианте для JavaScript. Установлен флаг x, который игнорирует пробельные символы в выражении, что позволяет его оставить многострочным, как в варианте для Java. Также доступен однострочный вариант.
(?iu)\b(?:(?:(?:у|[нз]а|(?:хитро|не)?вз?[ыьъ]|с[ьъ]|(?:и|ра)[зс]ъ?|(?:о[тб]|п[оа]д)[ьъ]?|(?:.\B)+?[оаеи-])-?)?(?:[её](?:б(?!о[рй]|рач)|п[уа](?:ц|тс))|и[пб][ае][тцд][ьъ]).*?|(?:(?:н[иеа]|ра[зс]|[зд]?[ао](?:т|дн[оа])?|с(?:м[еи])?|а[пб]ч)-?)?ху(?:[яйиеёю]|л+и(?!ган)).*?|бл(?:[эя]|еа?)(?:[дт][ьъ]?)?|\S*?(?:п(?:[иеё]зд|ид[аое]?р|ед(?:р(?!о)|[аое]р|ик)|охую)|бля(?:[дбц]|тс)|[ое]ху[яйиеё]|хуйн).*?|(?:о[тб]?|про|на|вы)?м(?:анд(?:[ауеыи](?:л(?:и[сзщ])?[ауеиы])?|ой|[ао]в.*?|юк(?:ов|[ауи])?|е[нт]ь|ища)|уд(?:[яаиое].+?|е?н(?:[ьюия]|ей))|[ао]л[ао]ф[ьъ](?:[яиюе]|[еёо]й))|елд[ауые].*?|ля[тд]ь|(?:[нз]а|по)х)\b
(?iux)\b(?:
(?:(?:у|[нз]а|(?:хитро|не)?вз?[ыьъ]|с[ьъ]|(?:и|ра)[зс]ъ?|(?:о[тб]|п[оа]д)[ьъ]?|(?:.\B)+?[оаеи-])-?)?(?:
[её](?:б(?!о[рй]|рач)|п[уа](?:ц|тс))|
и[пб][ае][тцд][ьъ]
).*?|
(?:(?:н[иеа]|ра[зс]|[зд]?[ао](?:т|дн[оа])?|с(?:м[еи])?|а[пб]ч)-?)?ху(?:[яйиеёю]|л+и(?!ган)).*?|
бл(?:[эя]|еа?)(?:[дт][ьъ]?)?|
\S*?(?:
п(?:
[иеё]зд|
ид[аое]?р|
ед(?:р(?!о)|[аое]р|ик)|
охую
)|
бля(?:[дбц]|тс)|
[ое]ху[яйиеё]|
хуйн
).*?|
(?:о[тб]?|про|на|вы)?м(?:
анд(?:[ауеыи](?:л(?:и[сзщ])?[ауеиы])?|ой|[ао]в.*?|юк(?:ов|[ауи])?|е[нт]ь|ища)|
уд(?:[яаиое].+?|е?н(?:[ьюия]|ей))|
[ао]л[ао]ф[ьъ](?:[яиюе]|[еёо]й)
)|
елд[ауые].*?|
ля[тд]ь|
(?:[нз]а|по)х
)\b
(?<![а-яё])(?:(?:(?:у|[нз]а|(?:хитро|не)?вз?[ыьъ]|с[ьъ]|(?:и|ра)[зс]ъ?|(?:о[тб]|п[оа]д)[ьъ]?|(?:\S(?=[а-яё]))+?[оаеи-])-?)?(?:[её](?:б(?!о[рй]|рач)|п[уа](?:ц|тс))|и[пб][ае][тцд][ьъ]).*?|(?:(?:н[иеа]|ра[зс]|[зд]?[ао](?:т|дн[оа])?|с(?:м[еи])?|а[пб]ч)-?)?ху(?:[яйиеёю]|л+и(?!ган)).*?|бл(?:[эя]|еа?)(?:[дт][ьъ]?)?|\S*?(?:п(?:[иеё]зд|ид[аое]?р|ед(?:р(?!о)|[аое]р|ик)|охую)|бля(?:[дбц]|тс)|[ое]ху[яйиеё]|хуйн).*?|(?:о[тб]?|про|на|вы)?м(?:анд(?:[ауеыи](?:л(?:и[сзщ])?[ауеиы])?|ой|[ао]в.*?|юк(?:ов|[ауи])?|е[нт]ь|ища)|уд(?:[яаиое].+?|е?н(?:[ьюия]|ей))|[ао]л[ао]ф[ьъ](?:[яиюе]|[еёо]й))|елд[ауые].*?|ля[тд]ь|(?:[нз]а|по)х)(?![а-яё])
(?iu)(?<![а-яё])(?:(?:(?:у|[нз]а|(?:хитро|не)?вз?[ыьъ]|с[ьъ]|(?:и|ра)[зс]ъ?|(?:о[тб]|п[оа]д)[ьъ]?|(?:\S(?=[а-яё]))+?[оаеи-])-?)?(?:[её](?:б(?!о[рй]|рач)|п[уа](?:ц|тс))|и[пб][ае][тцд][ьъ]).*?|(?:(?:н[иеа]|ра[зс]|[зд]?[ао](?:т|дн[оа])?|с(?:м[еи])?|а[пб]ч)-?)?ху(?:[яйиеёю]|л+и(?!ган)).*?|бл(?:[эя]|еа?)(?:[дт][ьъ]?)?|\S*?(?:п(?:[иеё]зд|ид[аое]?р|ед(?:р(?!о)|[аое]р|ик)|охую)|бля(?:[дбц]|тс)|[ое]ху[яйиеё]|хуйн).*?|(?:о[тб]?|про|на|вы)?м(?:анд(?:[ауеыи](?:л(?:и[сзщ])?[ауеиы])?|ой|[ао]в.*?|юк(?:ов|[ауи])?|е[нт]ь|ища)|уд(?:[яаиое].+?|е?н(?:[ьюия]|ей))|[ао]л[ао]ф[ьъ](?:[яиюе]|[еёо]й))|елд[ауые].*?|ля[тд]ь|(?:[нз]а|по)х)(?![а-яё])
(?iux)(?<![а-яё])(?:
(?:(?:у|[нз]а|(?:хитро|не)?вз?[ыьъ]|с[ьъ]|(?:и|ра)[зс]ъ?|(?:о[тб]|п[оа]д)[ьъ]?|(?:\S(?=[а-яё]))+?[оаеи-])-?)?(?:
[её](?:б(?!о[рй]|рач)|п[уа](?:ц|тс))|
и[пб][ае][тцд][ьъ]
).*?|
(?:(?:н[иеа]|ра[зс]|[зд]?[ао](?:т|дн[оа])?|с(?:м[еи])?|а[пб]ч)-?)?ху(?:[яйиеёю]|л+и(?!ган)).*?|
бл(?:[эя]|еа?)(?:[дт][ьъ]?)?|
\S*?(?:
п(?:
[иеё]зд|
ид[аое]?р|
ед(?:р(?!о)|[аое]р|ик)|
охую
)|
бля(?:[дбц]|тс)|
[ое]ху[яйиеё]|
хуйн
).*?|
(?:о[тб]?|про|на|вы)?м(?:
анд(?:[ауеыи](?:л(?:и[сзщ])?[ауеиы])?|ой|[ао]в.*?|юк(?:ов|[ауи])?|е[нт]ь|ища)|
уд(?:[яаиое].+?|е?н(?:[ьюия]|ей))|
[ао]л[ао]ф[ьъ](?:[яиюе]|[еёо]й)
)|
елд[ауые].*?|
ля[тд]ь|
(?:[нз]а|по)х
)(?![а-яё])
@LEv145
Copy link

LEv145 commented Dec 22, 2022

изображение
У меня странно работает regex, тк (.*|(ас)?(ну.*?|и(ли)?[нщктл]ь?)?) может, как (.*|)

@imDaniX
Copy link
Author

imDaniX commented Dec 22, 2022

У меня странно работает regex, тк (.*|(ас)?(ну.*?|и(ли)?[нщктл]ь?)?) может, как (.*|)

\b в начале и конце не просто так стоят - отвечают за детект границы слова.

@AlexanderMatveev
Copy link

Не могу заставить работать на https://regex101.com/ ни один вариант. Да и вообще грустно, неужели нет популярных решений не на регулярках

@imDaniX
Copy link
Author

imDaniX commented Apr 12, 2023

@AlexanderMatveev

Не могу заставить работать на https://regex101.com/ ни один вариант

Повторюсь - делалось под Java в первую очередь. Там regex101 появилась опция под Java 8, и всё вполне работает. И повторю другой момент - требуется использовать регулярку из regex-0.txt или regex-1.txt. Хотя можно сделать как у @LEv145 - добавить x во флаги, и тогда оно будет регулярку читать построчно (не помню, почему сам так изначально не сделал, но скорее всего просто не знал на тот момент).
В ближайшее время наверно обновлю гист - надо чуть больше пояснений добавить, да варианты для других ЯП.

Да и вообще грустно, неужели нет популярных решений не на регулярках

Я не находил.. но если честно, и не искал. Я начинал один проект, но потом понял, что в моем случае игра не стоит свеч. На мой взгляд, всё это в любом случае обойдется на раз-два, дай человеку волю только. То, что уже есть сейчас, и так покроет большую часть использований мата. Для всего остального есть ручная модерация.
Ну, и наверно, можно упомянуть вариант использования нейросетей. Не таких гигантов, вроде GPT, а небольших, более традиционных, обученных под конкретную задачу.

@hazartilirot
Copy link

Не могу заставить работать на https://regex101.com/ ни один вариант. Да и вообще грустно, неужели нет популярных решений не на регулярках

У меня вопрос, а зачем вообще Вам нагружать систему проверяя любой комментарий? Какой в этом смысл? Это бесполезная трата ресурсов, абсолютно лишнее. Не хочу обидеть автора - он молодец)

Просто, любой пользователь который хочет написать матом, сделает замену символов внутри слова и всё равно мат пролетит в паблик. Для подобного рода модерации существует администрация на сайта, форумах или чатах. Даже тот же Телеграм не предоставляет таких "понтов". Репортуй админу на сообщение и жди когда отреагируют.

Реджекс очень хорош, сам люблю, но не в данном случае. ИМХО)

@dhawkmoon
Copy link

Не могу заставить работать на https://regex101.com/ ни один вариант. Да и вообще грустно, неужели нет популярных решений не на регулярках

Попробуй так:

(?<=(^|[^а-я]))(([уyu]|[нзnz3][аa]|(хитро|не)?[вvwb][зz3]?[ыьъi]|[сsc][ьъ']|(и|[рpr][аa4])[зсzs]ъ?|([оo0][тбtb6]|[пp][оo0][дd9])[ьъ']?|(.\B)+?[оаеиeo])?-?([еёe][бb6](?!о[рй])|и[пб][ае][тц]).*?|([нn][иеаaie]|([дпdp]|[вv][еe3][рpr][тt])[оo0]|[рpr][аa][зсzc3]|[з3z]?[аa]|с(ме)?|[оo0]([тt]|дно)?|апч)?-?[хxh][уuy]([яйиеёюuie]|ли(?!ган)).*?|([вvw][зы3z]|(три|два|четыре)жды|(н|[сc][уuy][кk])[аa])?-?[бb6][лl]([яy](?!(х|ш[кн]|мб)[ауеыио]).*?|[еэe][дтdt][ь']?)|([рp][аa][сзc3z]|[знzn][аa]|[соsc]|[вv][ыi]?|[пp]([еe][рpr][еe]|[рrp][оиioеe]|[оo0][дd])|и[зс]ъ?|[аоao][тt])?[пpn][иеёieu][зz3][дd9].*?|([зz3][аa])?[пp][иеieu][дd][аоеaoe]?[рrp](ну.*?|[оаoa][мm]|([аa][сcs])?([иiu]([лl][иiu])?[нщктлtlsn]ь?)?|([оo](ч[еиei])?|[аa][сcs])?[кk]([оo]й)?|[юu][гg])[ауеыauyei]?|[мm][аa][нnh][дd]([ауеыayueiи]([лl]([иi][сзc3щ])?[ауеыauyei])?|[оo][йi]|[аоao][вvwb][оo](ш|sh)[ь']?([e]?[кk][ауеayue])?|юк(ов|[ауи])?)|[мm][уuy][дd6]([яyаиоaiuo0].*?|[еe]?[нhn]([ьюия'uiya]|ей))|мля([тд]ь)?|лять|([нз]а|по)х|м[ао]л[ао]фь([яию]|[её]й))($|[^а-я]),

флаги поставь ui

@imDaniX
Copy link
Author

imDaniX commented Aug 9, 2023

Обновил гист - дополнил документацию, расширил, а местами и упростил регулярку, добавил "официальный" вариант под JS (хотя он всё ещё требует правок).
Варианты с транскриптом пока в долговом ящике. Наверно, однажды сделаю какой-нибудь скрипт, чтобы можно было самостоятельно расширить регулярку в вариант с транскриптом.
Файлы теперь будут называться Swears Язык.regex - тип файла добавил для подсветки синтаксиса здесь. Буду придерживаться такого формата, чтобы можно было автоматически подтягивать регулярки прямо с гиста в будущем.

@MeexReay
Copy link

MeexReay commented Aug 23, 2023

Запустил на Python 3.11

re.compile(r"(?<=^|[^а-яё])(?:(?:(?:у|[нз]а|(?:хитро|не)?вз?[ыьъ]|с[ьъ]|(?:и|ра)[зс]ъ?|(?:о[тб]|п[оа]д)[ьъ]?|(?:\S(?=[а-яё]))+?[оаеи-])-?)?(?:[её](?:б(?!о[рй]|рач)|п[уа](?:ц|тс))|и[пб][ае][тцд][ьъ]).*?|(?:(?:н[иеа]|ра[зс]|[зд]?[ао](?:т|дн[оа])?|с(?:м[еи])?|а[пб]ч)-?)?ху(?:[яйиеёю]|л+и(?!ган)).*?|бл(?:[эя]|еа?)(?:[дт][ьъ]?)?|\S*?(?:п(?:[иеё]зд|ид[аое]?р|ед(?:р(?!о)|[аое]р|ик))|бля(?:[дбц]|тс)|[ое]ху[яйиеёю]|хуйн).*?|(?:о[тб]?|про|на|вы)?м(?:анд(?:[ауеыи](?:л(?:и[сзщ])?[ауеиы])?|ой|[ао]в.*?|юк(?:ов|[ауи])?|е[нт]ь|ища)|уд(?:[яаиое].+?|е?н(?:[ьюия]|ей))|[ао]л[ао]ф[ьъ](?:[яиюе]|[еёо]й))|елд[ауые].*?|ля[тд]ь|(?:[нз]а|по)х)(?=$|[^а-яё])")
# Ошибка re.error: look-behind requires fixed-width pattern

Обидно, т.к на regex101 хорошо работает :/

Полная ошибка
Traceback (most recent call last):
  File "C:\Users\user\Desktop\regex_test.py", line 4, in <module>
    re.compile(r"(?<=^|[^а-яё])(?:(?:(?:у|[нз]а|(?:хитро|не)?вз?[ыьъ]|с[ьъ]|(?:и|ра)[зс]ъ?|(?:о[тб]|п[оа]д)[ьъ]?|(?:\S(?=[а-яё]))+?[оаеи-])-?)?(?:[её](?:б(?!о[рй]|рач)|п[уа](?:ц|тс))|и[пб][ае][тцд][ьъ]).*?|(?:(?:н[иеа]|ра[зс]|[зд]?[ао](?:т|дн[оа])?|с(?:м[еи])?|а[пб]ч)-?)?ху(?:[яйиеёю]|л+и(?!ган)).*?|бл(?:[эя]|еа?)(?:[дт][ьъ]?)?|\S*?(?:п(?:[иеё]зд|ид[аое]?р|ед(?:р(?!о)|[аое]р|ик))|бля(?:[дбц]|тс)|[ое]ху[яйиеёю]|хуйн).*?|(?:о[тб]?|про|на|вы)?м(?:анд(?:[ауеыи](?:л(?:и[сзщ])?[ауеиы])?|ой|[ао]в.*?|юк(?:ов|[ауи])?|е[нт]ь|ища)|уд(?:[яаиое].+?|е?н(?:[ьюия]|ей))|[ао]л[ао]ф[ьъ](?:[яиюе]|[еёо]й))|елд[ауые].*?|ля[тд]ь|(?:[нз]а|по)х)(?=$|[^а-яё])")
  File "C:\Users\user\Local\Programs\Lib\re\__init__.py", line 227, in compile
    return _compile(pattern, flags)
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\user\Programs\Python\Python311\Lib\re\__init__.py", line 294, in _compile
    p = _compiler.compile(pattern, flags)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\user\AppData\Programs\Python\Lib\re\_compiler.py", line 747, in compile
    code = _code(p, flags)
           ^^^^^^^^^^^^^^^
  File "C:\Users\user\AppData\Local\Programs\Python311\Lib\re\_compiler.py", line 580, in _code
    _compile(code, p.data, flags)
  File "C:\Users\user\AppData\Local\Programs\Python311\Lib\re\_compiler.py", line 153, in _compile
    raise error("look-behind requires fixed-width pattern")
re.error: look-behind requires fixed-width pattern

@imDaniX
Copy link
Author

imDaniX commented Aug 24, 2023

@MeexReay Обновил файлик под JS - теперь работает и на Питоне. Не забудь проставить флаги flags = re.I | re.U.

@yet-another-user-name
Copy link

Javascript-версия триггерится на слово "плохую" (Java-версию не тестировал)

@imDaniX
Copy link
Author

imDaniX commented Dec 25, 2023

Javascript-версия триггерится на слово "плохую" (Java-версию не тестировал)

Вижу, и правда. Переделал.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment