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*?(?:
п(?:
[иеё]зд|
ид[аое]?р|
ед(?:р(?!о)|[аое]р|ик)|
охую
)|
бля(?:[дбц]|тс)|
[ое]ху[яйиеё]|
хуйн
).*?|
(?:о[тб]?|про|на|вы)?м(?:
анд(?:[ауеыи](?:л(?:и[сзщ])?[ауеиы])?|ой|[ао]в.*?|юк(?:ов|[ауи])?|е[нт]ь|ища)|
уд(?:[яаиое].+?|е?н(?:[ьюия]|ей))|
[ао]л[ао]ф[ьъ](?:[яиюе]|[еёо]й)
)|
елд[ауые].*?|
ля[тд]ь|
(?:[нз]а|по)х
)(?![а-яё])
@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