Files
smart-speaker/app/core/roman.py

44 lines
1.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Roman numeral parsing helpers."""
import re
_ROMAN_VALID_RE = re.compile(
r"^M{0,3}(CM|CD|D?C{0,3})"
r"(XC|XL|L?X{0,3})"
r"(IX|IV|V?I{0,3})$"
)
_ROMAN_TOKEN_RE = re.compile(r"(?<![A-Za-zА-Яа-яЁё0-9])[IVXLCDMivxlcdm]+(?![A-Za-zА-Яа-яЁё0-9])")
_ROMAN_VALUES = {"I": 1, "V": 5, "X": 10, "L": 50, "C": 100, "D": 500, "M": 1000}
def roman_to_int(token: str) -> int | None:
if not token:
return None
roman = token.strip().upper()
if not roman or not _ROMAN_VALID_RE.fullmatch(roman):
return None
total = 0
prev = 0
for char in reversed(roman):
value = _ROMAN_VALUES[char]
if value < prev:
total -= value
else:
total += value
prev = value
return total
def replace_roman_numerals(text: str) -> str:
if not text:
return text
def _repl(match: re.Match) -> str:
token = match.group(0)
value = roman_to_int(token)
return str(value) if value is not None else token
return _ROMAN_TOKEN_RE.sub(_repl, text)