diff --git a/normalization/languages/swedish/number_normalizer.py b/normalization/languages/swedish/number_normalizer.py index c145e79..83abe51 100644 --- a/normalization/languages/swedish/number_normalizer.py +++ b/normalization/languages/swedish/number_normalizer.py @@ -322,7 +322,7 @@ def _parse_0_999(self, words: list[str], i: int, n: int) -> tuple[int, int] | No return i + 1, 0 if _fold(words[i]) == "hundra": - tail = self._parse_0_99(words, i + 1, n) + tail = self._parse_0_99_after_hundred(words, i + 1, n) if tail is not None: je, tv = tail return je, 100 + tv @@ -334,7 +334,7 @@ def _parse_0_999(self, words: list[str], i: int, n: int) -> tuple[int, int] | No return None base = m * 100 j = i + 2 - tail = self._parse_0_99(words, j, n) + tail = self._parse_0_99_after_hundred(words, j, n) if tail is not None: je, tv = tail return je, base + tv @@ -342,6 +342,23 @@ def _parse_0_999(self, words: list[str], i: int, n: int) -> tuple[int, int] | No return self._parse_0_99(words, i, n) + def _parse_0_99_after_hundred( + self, words: list[str], i: int, n: int + ) -> tuple[int, int] | None: + """Parse 0–99, additionally accepting standalone ``en``/``ett`` as 1. + + A bare ``en``/``ett`` is ambiguous with the article elsewhere, so + ``_parse_0_99`` leaves it as a word. After a hundreds block it can only + be the unit 1 (``hundra ett`` = 101, ``hundra ett tusen`` = 101000), so + it is safe to read here. + """ + result = self._parse_0_99(words, i, n) + if result is not None: + return result + if i < n and _fold(words[i]) in ("en", "ett"): + return i + 1, 1 + return None + def _continues_number(self, word: str) -> bool: fw = _fold(word) if fw == "hundra" or fw == "tusen": diff --git a/tests/unit/languages/swedish_number_normalizer_test.py b/tests/unit/languages/swedish_number_normalizer_test.py index b05477d..8edcc96 100644 --- a/tests/unit/languages/swedish_number_normalizer_test.py +++ b/tests/unit/languages/swedish_number_normalizer_test.py @@ -67,3 +67,21 @@ def test_kronor_word_not_treated_as_currency_suffix( normalizer: SwedishNumberNormalizer, ) -> None: assert normalizer("25 kronor") == "25 kronor" + + +@pytest.mark.parametrize( + ("text", "expected"), + [ + ("hundra ett", "101"), + ("två hundra en", "201"), + ("hundra ett tusen", "101000"), + ("två hundra ett tusen", "201000"), + ("tre hundra ett tusen fem", "301005"), + ], +) +def test_unit_one_after_hundred_keeps_grouping( + normalizer: SwedishNumberNormalizer, text: str, expected: str +) -> None: + """``en``/``ett`` as the ones part after a hundreds block is the unit 1, so + the thousands multiplier is not dropped (``hundra ett tusen`` = 101000).""" + assert normalizer(text) == expected