Фикс с повторами символов

This commit is contained in:
2026-02-20 23:11:10 +07:00
parent 4d1b8911b3
commit a5c586e700

View File

@@ -10,7 +10,7 @@ Middleware для проверки сообщений на запрещённы
- Нет уведомлений в режиме тишины - Нет уведомлений в режиме тишины
""" """
from typing import Callable, Dict, Any, Awaitable, Optional, Set from typing import Callable, Dict, Any, Awaitable, Optional
import re import re
import unicodedata import unicodedata
@@ -20,7 +20,7 @@ from aiogram.exceptions import TelegramBadRequest
from configs import settings, UNICODE_MAP, LATIN_TO_CYRILLIC, CYRILLIC_NORMALIZE from configs import settings, UNICODE_MAP, LATIN_TO_CYRILLIC, CYRILLIC_NORMALIZE
from database import get_manager, BanWordType from database import get_manager, BanWordType
from bot.special import process_text, extract_words, get_lemma from bot.special import extract_words, get_lemma
from middleware.loggers import logger from middleware.loggers import logger
__all__ = ("BanWordsMiddleware",) __all__ = ("BanWordsMiddleware",)
@@ -40,7 +40,7 @@ class TextNormalizer:
FULL_MAP.update(UNICODE_MAP) FULL_MAP.update(UNICODE_MAP)
# Символы-разделители, которые могут быть вставлены между буквами # Символы-разделители, которые могут быть вставлены между буквами
SEPARATORS = re.compile(r'[\s\.\-_,;:|]+', re.UNICODE) SEPARATORS = re.compile(r'[\s.\-_,;:|]+', re.UNICODE)
# Паттерн для поиска повторяющихся букв (3+ раза) # Паттерн для поиска повторяющихся букв (3+ раза)
REPEAT_PATTERN = re.compile(r'([а-яёa-z])\1{2,}', re.IGNORECASE) REPEAT_PATTERN = re.compile(r'([а-яёa-z])\1{2,}', re.IGNORECASE)
@@ -68,15 +68,10 @@ class TextNormalizer:
@classmethod @classmethod
def collapse_repeats(cls, text: str, max_repeat: int = 2) -> str: def collapse_repeats(cls, text: str, max_repeat: int = 2) -> str:
"""
Заменяет повторения символов более max_repeat подряд на один/два символа.
По умолчанию оставляет максимум 2 (леееейн → леейн? но обычно хватит 2).
Можно настроить: для банворда "лейн" превратит "леееейн" в "леейн", что всё равно содержит "лейн".
"""
def repl(m): def repl(m):
ch = m.group(1) ch = m.group(1)
# Оставляем два символа, чтобы не терять удвоенные буквы (например, "дд" в слове "поддон") return ch # вместо ch * 2 — теперь схлопываем до одного символа
return ch * 2
return cls.REPEAT_PATTERN.sub(repl, text) return cls.REPEAT_PATTERN.sub(repl, text)
@classmethod @classmethod
@@ -160,9 +155,9 @@ class BanWordsMiddleware(BaseMiddleware):
Возвращает словарь с причиной блокировки или None. Возвращает словарь с причиной блокировки или None.
""" """
# 1. Повторяющиеся символы (например, "леееейн") — блокируем сразу # 1. Повторяющиеся символы (например, "леееейн") — блокируем сразу
repeat_result = self._check_repeated_chars(text) # repeat_result = self._check_repeated_chars(text)
if repeat_result: # if repeat_result:
return repeat_result # return repeat_result
# 2. Получаем кэшированные списки # 2. Получаем кэшированные списки
substring_words = self.manager.get_banwords_cached(BanWordType.SUBSTRING) substring_words = self.manager.get_banwords_cached(BanWordType.SUBSTRING)