diff --git a/etpgrf/config.py b/etpgrf/config.py index 000775f..26e3d52 100644 --- a/etpgrf/config.py +++ b/etpgrf/config.py @@ -633,8 +633,11 @@ DEFAULT_POST_UNITS = [ 'кв', 'куб', 'мм', 'см', 'м', 'км', 'л', 'мл', 'сот', 'га', 'сек', 'с.', 'мин', 'ч', 'руб', 'коп', + 'дБ', 'Вт', 'кВт', 'МВт', 'ГВт', 'А', 'В', 'Ом', 'Па', 'кПа', 'МПа', 'Бар', 'кБар', 'Гц', 'кГц', 'МГц', 'ГГц', + 'рад', 'К', '°C', '°F', '%', 'мкм', 'нм', 'А°', 'эВ', 'Дж', 'кДж', 'МДж', 'пкФ', 'нФ', 'мкФ', 'мФ', 'Ф', + 'Гн', 'мГн', 'мкГн', 'Тл', 'Гс', 'эрг', 'тыс', 'млн', 'млрд', 'трлн', 'трлрд', - 'пп', 'стр', 'рис', 'табл', 'гл', 'п', 'шт', 'об' + 'пп', 'стр', 'рис', 'табл', 'гл', 'п', 'шт', 'об', # Английские 'pp', 'p', 'para', 'sect', 'fig', 'vol', 'ed', ] diff --git a/etpgrf/layout.py b/etpgrf/layout.py index d51d41a..69127c8 100644 --- a/etpgrf/layout.py +++ b/etpgrf/layout.py @@ -76,23 +76,25 @@ class LayoutProcessor: elif isinstance(self.process_units, (list, tuple, set)): all_post_units.extend(self.process_units) - units_pattern_part = '' - # Общий паттерн для всех остальных единиц if all_post_units: sorted_units = sorted(all_post_units, key=len, reverse=True) - units_pattern_part = '|'.join(map(regex.escape, sorted_units)) + # Создаем "чистый" паттерн без точек для универсальности + units_pattern_part_clean = '|'.join(map(regex.escape, [u.replace('.', '') for u in sorted_units])) + # Создаем паттерн, который включает единицы с точками, для простых замен + units_pattern_part_full = '|'.join(map(regex.escape, sorted_units)) - if units_pattern_part: + if units_pattern_part_full: # Простые единицы: число + единица - self._post_units_pattern = regex.compile(rf'({self._NUMBER_PATTERN})\s+({units_pattern_part})(?!\w)') + self._post_units_pattern = regex.compile(rf'({self._NUMBER_PATTERN})\s+({units_pattern_part_full})(?!\w)') # Паттерн для составных единиц: ищет пару "единица." + "единица", разделенную пробелами (или без них). # Обязательное наличие точки `\.` после первой единицы делает цикл обработки безопасным. - self._complex_unit_pattern = regex.compile(r'\b(' + units_pattern_part + r')\.(\s*)(' + units_pattern_part + r')(?!\w)') + # Используем "чистый" паттерн, чтобы правило работало независимо от того, как определена единица ('в' или 'в.') + self._complex_unit_pattern = regex.compile(r'\b(' + units_pattern_part_clean + r')\.(\s*)(' + units_pattern_part_clean + r')(?!\w)') # Паттерн для математических операций между единицами math_ops_pattern = '|'.join(map(regex.escape, UNIT_MATH_OPERATORS)) self._math_unit_pattern = regex.compile( - r'\b(' + units_pattern_part + r')\s*(' + math_ops_pattern + r')\s*(' + units_pattern_part + r')(?!\w)') + r'\b(' + units_pattern_part_clean + r')\s*(' + math_ops_pattern + r')\s*(' + units_pattern_part_clean + r')(?!\w)') # Паттерн для пред-позиционных единиц self._pre_units_pattern = regex.compile( diff --git a/tests/test_layout.py b/tests/test_layout.py index 74c1d86..31839ab 100644 --- a/tests/test_layout.py +++ b/tests/test_layout.py @@ -108,7 +108,7 @@ LAYOUT_TEST_CASES = [ # ('ru', "Дом 120 кв.м. / Участок 6 сот.", f"Дом 120{CHAR_NBSP}кв.м. / Участок 6{CHAR_NBSP}сот."), # ('ru', "Гробик кладут в ямку 2 кв. м.", f"Гробик кладут в ямку 2 кв. м."), ('ru', "IV-X вв.", f"IV-X{CHAR_NBSP}вв."), - ('ru', "IV в. н. э.", f"IV{CHAR_NBSP}в. н.{CHAR_THIN_SP}э."), + ('ru', "IV в. н. э.", f"IV{CHAR_NBSP}в.{CHAR_THIN_SP}н.{CHAR_THIN_SP}э."), ('ru+en', "Хаммурапи (1792 - 1750 до н. э.)", f"Хаммурапи (1792 - 1750 до н.{CHAR_THIN_SP}э.)"), @@ -119,7 +119,12 @@ LAYOUT_TEST_CASES = [ ('ru', "Площадь 150 тыс. кв. км.", f"Площадь 150{CHAR_NBSP}тыс.{CHAR_THIN_SP}кв.{CHAR_THIN_SP}км."), ('ru', "Скорость 90 км/ч", f"Скорость 90{CHAR_NBSP}км/ч"), ('ru', "Скорость 90 км / ч", f"Скорость 90{CHAR_NBSP}км/ч"), - ('ru', "В 500 г. н. э.", f"В 500{CHAR_NBSP}г. н.{CHAR_THIN_SP}э."), + ('ru', "В 500 г. н. э.", f"В 500{CHAR_NBSP}г.{CHAR_THIN_SP}н.{CHAR_THIN_SP}э."), + ('ru', "Пластинка 45 мин. об.", f"Пластинка 45{CHAR_NBSP}мин.{CHAR_THIN_SP}об."), + ('ru', "Пластинка 45 об. мин.", f"Пластинка 45{CHAR_NBSP}об.{CHAR_THIN_SP}мин."), + ('ru', "За окном 15°C", f"За окном 15°C"), + ('ru', "За окном 15 °C", f"За окном 15{CHAR_NBSP}°C"), + ('ru', "HiFi 20 Гц - 20 кГц", f"HiFi 20{CHAR_NBSP}Гц - 20{CHAR_NBSP}кГц"), # Сложные единицы (склеиваются тонкой шпацией, привязываются к числу неразрывным пробелом) ('ru', "Дом 120 кв.м. / Участок 6 сот.", f"Дом 120{CHAR_NBSP}кв.{CHAR_THIN_SP}м. / Участок 6{CHAR_NBSP}сот."),