fix: исправлен алгоритм парсинга счетов - удаление найденных совпадений
Заменен подход с негативными lookbehind на удаление найденных совпадений: - Сначала находим все 'КАРТА СЧЕТ' паттерны - Заменяем их пробелами в копии текста - Потом ищем только счета в оставшемся тексте - Это предотвращает дублирование типа '25-22-63-30-90-57-17'
This commit is contained in:
@@ -113,29 +113,33 @@ def parse_accounts_from_message(text: str) -> List[str]:
|
|||||||
return []
|
return []
|
||||||
|
|
||||||
accounts = []
|
accounts = []
|
||||||
found_accounts_only = set() # Для отслеживания уже найденных счетов
|
|
||||||
|
|
||||||
# Паттерн 1: номер карты (4 цифры) + пробел + счет (7 пар цифр)
|
# Паттерн 1: номер карты (4 цифры) + пробел + счет (7 пар цифр)
|
||||||
# Используем негативный lookbehind чтобы не ловить цифры перед картой
|
pattern_with_card = r'(\d{4})\s+(\d{2}[-\s]?\d{2}[-\s]?\d{2}[-\s]?\d{2}[-\s]?\d{2}[-\s]?\d{2}[-\s]?\d{2})'
|
||||||
pattern_with_card = r'(?<!\d)(\d{4})\s+(\d{2}[-\s]?\d{2}[-\s]?\d{2}[-\s]?\d{2}[-\s]?\d{2}[-\s]?\d{2}[-\s]?\d{2})(?!\d)'
|
|
||||||
matches_with_card = re.findall(pattern_with_card, text)
|
|
||||||
|
|
||||||
for card, account in matches_with_card:
|
# Находим все совпадения с картой и удаляем их из текста
|
||||||
|
text_copy = text
|
||||||
|
for match in re.finditer(pattern_with_card, text):
|
||||||
|
card = match.group(1)
|
||||||
|
account = match.group(2)
|
||||||
formatted = format_account_number(account)
|
formatted = format_account_number(account)
|
||||||
if formatted:
|
if formatted:
|
||||||
full_account = f"{card} {formatted}"
|
full_account = f"{card} {formatted}"
|
||||||
if full_account not in accounts:
|
if full_account not in accounts:
|
||||||
accounts.append(full_account)
|
accounts.append(full_account)
|
||||||
found_accounts_only.add(formatted) # Запоминаем этот счет
|
# Удаляем это совпадение из копии текста, чтобы не найти повторно
|
||||||
|
text_copy = text_copy.replace(match.group(0), ' ' * len(match.group(0)))
|
||||||
|
|
||||||
# Паттерн 2: только счет (7 пар цифр) БЕЗ карты перед ним
|
# Паттерн 2: только счет (7 пар цифр) в оставшемся тексте
|
||||||
# Негативный lookbehind для проверки что перед счетом нет "4 цифры + пробел"
|
pattern_only_account = r'\b\d{2}[-\s]?\d{2}[-\s]?\d{2}[-\s]?\d{2}[-\s]?\d{2}[-\s]?\d{2}[-\s]?\d{2}\b'
|
||||||
pattern_only_account = r'(?<!\d{4}\s)(?<!\d)\d{2}[-\s]?\d{2}[-\s]?\d{2}[-\s]?\d{2}[-\s]?\d{2}[-\s]?\d{2}[-\s]?\d{2}(?!\d)'
|
matches_only = re.findall(pattern_only_account, text_copy)
|
||||||
matches_only = re.findall(pattern_only_account, text)
|
|
||||||
|
|
||||||
for match in matches_only:
|
for match in matches_only:
|
||||||
formatted = format_account_number(match)
|
formatted = format_account_number(match)
|
||||||
if formatted and formatted not in found_accounts_only and formatted not in accounts:
|
if formatted and formatted not in accounts:
|
||||||
|
# Дополнительная проверка - этот счет не должен быть частью уже найденных "карта + счет"
|
||||||
|
is_duplicate = any(formatted in acc for acc in accounts)
|
||||||
|
if not is_duplicate:
|
||||||
accounts.append(formatted)
|
accounts.append(formatted)
|
||||||
|
|
||||||
return accounts
|
return accounts
|
||||||
|
|||||||
Reference in New Issue
Block a user