Этот баг возник из-за очень хитрой цепочки событий!
Давайте разберем, почему в 2025 году получилось [1, 2, 3]: Сразу после 2025 года
в файле идет блок календарный год ... I квартал ... II квартал ... III квартал
... IV квартал. Наш обрезчик хвоста (который мы настраивали для защиты от
склеивания) нашел все эти маркеры и обрезал текст по последнему из них — перед
IV квартал. В итоге в текст для 2025 года попал хвост: (год) ... I квартал ...
II квартал ... III квартал. Парсер дошел до поиска кварталов, увидел явные слова
I, II, III квартал и решил, что они важнее, чем маркер (год), который стоял в
самом начале!
Решение: Нам нужно просто повысить приоритет маркера (год). Если он есть в
тексте записи, это 100% означает все 4 квартала, и искать разрозненные слова
«квартал» больше не нужно.
Замените блок --- 5. Ищем КВАРТАЛЫ во всем блоке записи --- на следующий:
Было:
# --- 5. Ищем КВАРТАЛЫ во всем блоке записи ---
paren_match = re.search(r'\(([^)]*квартал[^)]*)\)', full_record_text)
if paren_match:
roman_nums = re.findall(r'\b(I{1,3}|IV)\b', paren_match.group(1))
if roman_nums:
current_quarters = sorted(list(set([q_map[q] for q in roman_nums])))
else:
q_matches = re.findall(r'(?:I{1,3}|IV)\s*квартал', full_record_text)
if q_matches:
current_quarters = sorted(list(set([q_map[q] for q in q_matches])))
elif re.search(r'\(год\)', full_record_text):
current_quarters = [1, 2, 3, 4]
elif is_new_block:
current_quarters = []
Стало:
# --- 5. Ищем КВАРТАЛЫ во всем блоке записи ---
paren_match = re.search(r'\(([^)]*квартал[^)]*)\)', full_record_text)
if paren_match:
# 1-й приоритет: если кварталы указаны явно в скобках (I квартал, II квартал)
roman_nums = re.findall(r'\b(I{1,3}|IV)\b', paren_match.group(1))
if roman_nums:
current_quarters = sorted(list(set([q_map[q] for q in roman_nums])))
elif re.search(r'\(год\)', full_record_text):
# 2-й приоритет: если стоит маркер (год), игнорируем любой мусор и ставим все 4 квартала
current_quarters = [1, 2, 3, 4]
else:
# 3-й приоритет: свободный поиск слова "квартал" в тексте без скобок
q_matches = re.findall(r'(?:I{1,3}|IV)\s*квартал', full_record_text)
if q_matches:
current_quarters = sorted(list(set([q_map[q] for q in q_matches])))
elif is_new_block:
current_quarters = []
Теперь строгая иерархия защитит логику: если в блоке есть (год), парсер сразу
ставит [1, 2, 3, 4] и даже не пытается собирать чужие «I, II, III кварталы» из
оторванного хвоста 2026 года.