Expand ordinal suffix handling
This commit is contained in:
@@ -94,6 +94,35 @@ MONTHS_GENITIVE = [
|
||||
# Леммы единиц времени (для корректного падежа числительных)
|
||||
TIME_UNIT_LEMMAS = {"час", "минута", "секунда"}
|
||||
|
||||
# Суффиксы порядковых числительных для формата "1968-й", "1968-го", "1968-му", "1968-м" и т.п.
|
||||
_ORDINAL_SUFFIX_MAP = {
|
||||
# Masculine
|
||||
"ого": ("genitive", "m"),
|
||||
"его": ("genitive", "m"),
|
||||
"ому": ("dative", "m"),
|
||||
"ему": ("dative", "m"),
|
||||
"ым": ("instrumental", "m"),
|
||||
"им": ("instrumental", "m"),
|
||||
"ом": ("prepositional", "m"),
|
||||
"ем": ("prepositional", "m"),
|
||||
"ый": ("nominative", "m"),
|
||||
"ий": ("nominative", "m"),
|
||||
"й": ("nominative", "m"),
|
||||
"го": ("genitive", "m"),
|
||||
"му": ("dative", "m"),
|
||||
"м": ("prepositional", "m"),
|
||||
# Feminine
|
||||
"ая": ("nominative", "f"),
|
||||
"яя": ("nominative", "f"),
|
||||
"ую": ("accusative", "f"),
|
||||
"юю": ("accusative", "f"),
|
||||
"ой": ("genitive", "f"),
|
||||
"ей": ("genitive", "f"),
|
||||
# Neuter
|
||||
"ое": ("nominative", "n"),
|
||||
"ее": ("nominative", "n"),
|
||||
}
|
||||
|
||||
|
||||
def get_case_from_preposition(prep_token):
|
||||
"""Определяет падеж по предлогу."""
|
||||
@@ -128,16 +157,40 @@ def numbers_to_words(text: str) -> str:
|
||||
if not text:
|
||||
return ""
|
||||
|
||||
# 0. Обработка короткой записи годов с суффиксом: "1968-м", "в 1968-м году"
|
||||
preps_list = "|".join(map(re.escape, PREPOSITION_CASES.keys()))
|
||||
|
||||
# 0. Обработка короткой записи годов с суффиксом: "1968-й", "1968-го", "1968-му", "1968-м", "в 1968-м году"
|
||||
def replace_year_suffix_match(match):
|
||||
prep = match.group(1) # Предлог (в, во, о...)
|
||||
year_str = match.group(2) # Само число
|
||||
year_word = match.group(3) # Слово "год", "году" и т.д. (опционально)
|
||||
suffix = match.group(3) # Суффикс порядкового числительного
|
||||
year_word = match.group(4) # Слово "год", "году" и т.д. (опционально)
|
||||
|
||||
# Суффикс "-м/-ом" обычно соответствует предложному падежу
|
||||
words = convert_number(
|
||||
year_str, context_type="ordinal", case="prepositional", gender="m"
|
||||
)
|
||||
case = None
|
||||
gender = None
|
||||
|
||||
if prep:
|
||||
morph_case = get_case_from_preposition(prep.strip().lower())
|
||||
if morph_case:
|
||||
case = PYMORPHY_TO_NUM2WORDS.get(morph_case)
|
||||
|
||||
suffix_key = suffix.lower()
|
||||
suffix_case, suffix_gender = _ORDINAL_SUFFIX_MAP.get(suffix_key, (None, None))
|
||||
|
||||
if not case and suffix_case:
|
||||
case = suffix_case
|
||||
|
||||
if year_word:
|
||||
gender = "m"
|
||||
elif suffix_gender:
|
||||
gender = suffix_gender
|
||||
|
||||
if not case:
|
||||
case = "nominative"
|
||||
if not gender:
|
||||
gender = "m"
|
||||
|
||||
words = convert_number(year_str, context_type="ordinal", case=case, gender=gender)
|
||||
|
||||
prefix = f"{prep} " if prep else ""
|
||||
if year_word:
|
||||
@@ -145,7 +198,9 @@ def numbers_to_words(text: str) -> str:
|
||||
return f"{prefix}{words}"
|
||||
|
||||
text = re.sub(
|
||||
r"(?i)\b((?:в|во|о|об|обо|при)\s+)?(\d{3,4})[-‑–—](?:м|ом)\b(?:\s+(год[а-я]*))?",
|
||||
rf"(?i)\b((?:{preps_list})\s+)?(\d{{3,4}})[-‑–—]"
|
||||
r"(ого|его|ому|ему|ым|им|ом|ем|ый|ий|ая|яя|ую|юю|ой|ей|ое|ее|й|го|му|м)\b"
|
||||
r"(?:\s+(год[а-я]*))?",
|
||||
replace_year_suffix_match,
|
||||
text,
|
||||
)
|
||||
@@ -270,7 +325,6 @@ def numbers_to_words(text: str) -> str:
|
||||
|
||||
# Регулярка теперь захватывает (опционально) следующее слово для определения рода
|
||||
|
||||
preps_list = "|".join(map(re.escape, PREPOSITION_CASES.keys()))
|
||||
text = re.sub(
|
||||
rf"(?i)(?<!\w)((?:{preps_list})\s+)?([+-]?\d+(?:[.,]\d+)?)(?=(\s+[а-яА-ЯёЁ]+))?\b",
|
||||
replace_cardinal_match,
|
||||
|
||||
Reference in New Issue
Block a user