v0.0.39: оптимизация apply_replacements — однопроходная замена вместо N×re.sub (ускорение в разы)
Deploy drhider / validate (push) Canceled after 0s
Deploy drhider / validate (push) Canceled after 0s
This commit is contained in:
+33
-11
@@ -55,23 +55,45 @@ def apply_replacements(text: str, mapping: Dict[str, str], sorted_keys: List[str
|
||||
"""
|
||||
result = text
|
||||
|
||||
# ── Однопроходная замена: единый regex из всех ключей ──
|
||||
# Вместо N отдельных re.sub по всему тексту (O(N×text)) собираем
|
||||
# один паттерн из всех ключей и делаем один re.sub с callback (O(text)).
|
||||
if not sorted_keys:
|
||||
return result
|
||||
|
||||
alternatives = []
|
||||
for original in sorted_keys:
|
||||
replacement = mapping[original]
|
||||
|
||||
# Если сущность обрамлена буквами/цифрами — используем границы слова
|
||||
if original and original[0].isalnum() and original[-1].isalnum():
|
||||
pattern = r'(?<!\w)' + re.escape(original) + r'(?!\w)'
|
||||
if not original:
|
||||
continue
|
||||
esc = re.escape(original)
|
||||
# Границы слова — только если сущность обрамлена буквами/цифрами
|
||||
if original[0].isalnum() and original[-1].isalnum():
|
||||
alternatives.append(r'(?<!\w)' + esc + r'(?!\w)')
|
||||
else:
|
||||
pattern = re.escape(original)
|
||||
alternatives.append(esc)
|
||||
|
||||
new_result = re.sub(pattern, replacement, result)
|
||||
if not alternatives:
|
||||
return result
|
||||
|
||||
# Фоллбэк: Markdown-жирность могла разорвать строку
|
||||
combined = re.compile('|'.join(alternatives))
|
||||
matched_keys = set()
|
||||
|
||||
def _replace(match):
|
||||
m = match.group(0)
|
||||
matched_keys.add(m)
|
||||
return mapping.get(m, m)
|
||||
|
||||
result = combined.sub(_replace, result)
|
||||
|
||||
# ── Фоллбэк: Markdown-жирность могла разорвать строку ──
|
||||
# Применяется только к ключам, которые основная замена НЕ нашла
|
||||
# (например, «ООО **"**НУБЕС**"» — ** внутри сущности).
|
||||
for original in sorted_keys:
|
||||
if not original or original in matched_keys:
|
||||
continue
|
||||
md_pattern = _md_tolerant_pattern(original)
|
||||
if md_pattern is not None:
|
||||
new_result = re.sub(md_pattern, replacement, new_result)
|
||||
|
||||
result = new_result
|
||||
result = re.sub(md_pattern, mapping[original], result)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
Reference in New Issue
Block a user