Преобразовать число на итальянский и итальянский на номер в python

Мне нужен код Python для преобразования чисел на итальянский язык и обратно.

Looking at previous questions I learned that pynum2word does one way (num -> words) in several languages but alas, not in Italian.

Если такой код не существует в Python, я бы не прочь перевести такой код с Perl/Ruby/Java.

Благодарю.

2
nl ja de
Если вы посмотрите на источник модуля pynum2word, почему бы не заменить все английские строки в num2word_EN.py на их итальянские эквиваленты? Это взломанно, но вам не нужно было больше вникать в источник для достижения желаемого результата.
добавлено автор stib, источник
Или, может быть, испанский модуль будет ближе к итальянскому.
добавлено автор f p, источник

1 ответы

Чтобы сделать преобразование с итальянского на число, это довольно просто с использованием регулярных выражений:

import re


NUMBERS_SEQ = (
    ('dieci', '10'),
    ('undici', '11'),
    ('dodici', '12'),
    ('tredici', '13'),
    ('quattordici', '14'),
    ('quindici', '15'),
    ('sedici', '16'),
    ('diciasette', '17'),
    ('diciotto', '18'),
    ('diciannove', '19'),
    ('venti', '20'),
    ('trenta', '30'),
    ('quaranta', '40'),
    ('cinquanta', '50'),
    ('sessanta', '60'),
    ('settanta', '70'),
    ('ottanta', '80'),
    ('novanta', '90'),
    ('cento', '100'),
    ('mille', '1000'), ('mila', '1000'),
    ('milione', '1000000'), ('milioni', '1000000'),
    ('miliardo', '1000000000'), ('miliardi', '1000000000'),
    ('uno', '1'), ('un', '1'),
    ('due', '2'),
    ('tre', '3'),
    ('quattro', '4'),
    ('cinque', '5'),
    ('sei', '6'),
    ('sette', '7'),
    ('otto', '8'),
    ('nove', '9'),
    )

NUMBERS = dict(NUMBERS_SEQ)

TOKEN_REGEX = re.compile('|'.join('(%s)' % num for num, val in NUMBERS_SEQ))


def normalize_text(num_repr):
    '''Return a normalized version of *num_repr* that can be passed to let2num.'''

    return num_repr.lower().translate(None, ' \t')


def let2num(num_repr):
    '''Yield the numeric representation of *num_repr*.'''

    result = ''

    for token in (tok for tok in TOKEN_REGEX.split(num_repr) if tok):
        try:
            value = NUMBERS[token]
        except KeyError:
            if token not in ('di', 'e'):
                raise ValueError('Invalid number representation: %r' % num_repr)
            continue

        if token == 'miliardi':
            result += '0'*9
        elif token in ('mila','milioni'):
            zeros = '0' * value.count('0')
            piece = result[-3:].lstrip('0')
            result = (result[:-len(piece)-len(zeros)] +
                      piece +
                      zeros)
        elif not Результат:
            result = value
        else:
            length = len(value)
            non_zero_values = len(value.strip('0'))
            if token in ('cento', 'milione', 'miliardo'):
                if result[-1] != '0':
                    result = (result[:-length] +
                              result[-1] +
                              '0' * value.count('0'))
                    continue
            result = (result[:-length] +
                      value.rstrip('0') +
                      result[len(result) -length + non_zero_values:])
    return add_thousand_separator(result)


def add_thousand_separator(s, sep='.'):
    '''Return the numeric string s with the thousand separator.'''

    rev_s = s[::-1]
    tokens = [rev_s[i:i+3][::-1] for i in range(0, len(s), 3)][::-1]
    return sep.join(tokens)

Результат:

>>> let2num('unmilione')
'1.000.000'
>>> let2num('unmilionemilleduecento')
'1.001.200'
>>> let2num('unmilionemilleduecentotre')
'1.001.203'
>>> let2num('ventiquattro')
'24'
>>> let2num(normalize_text('Dieci milioni e CentoQuarantaTreMila miliardi di miliardi di miliardi Otto cento e quattro'))
'10.143.000.000.000.000.000.000.000.000.000.804'
>>> let2num('ventiquattromiliardicentotrentatremilionitredicimiladuecentouno')
'24.133.013.201'

Обратите внимание, что вы должны правильно набрать номер. В последнем примере, если вы введете строку: '... centotrentatremilione ...' , с ( wrong ) особый milione вместо milioni вы получаете:

>>> let2num('ventiquattromiliardicentotrentatremilionetredicimiladuecentouno')
'24.003.013.201'

Что не является «правильным». Но написание действительно неверно. Я считаю, что не должно быть слишком сложно разрешить milione как точный синоним для milioni или добавить некоторую проверку ошибок, чтобы она вызывала ошибку, если она обнаруживает неправильное написание. Просто знайте об этом.

В качестве предложения для отладки вышеуказанного кода (если вы хотите внести изменения) является добавление строки, например:

print 'token:', token, 'current Результат:', result

Как первая инструкция цикла for . Затем, наблюдая за тем, что делается, вы должны уметь распознавать «рассуждения» за кодом и видеть, где лежит ошибка.

Я думаю, что для другого преобразования было бы легко реализовать что-то, основанное на pynum2word . Если вы не знаете итальянский язык, я могу попытаться написать его.

2
добавлено
Эмм. Вы правы, я постараюсь это исправить.
добавлено автор Bakuriu, источник
@PeriodicMaintenance Хорошо, это нужно решить сейчас. Ошибка была в add_thousand_separator . Теперь это работает правильно.
добавлено автор Bakuriu, источник
Спасибо, это работает отлично! Что касается чисел для слов, было бы лучше добавить код непосредственно к pynum2word. Еще раз спасибо.
добавлено автор Periodic Maintenance, источник
... почти отлично. Я положил в ventiquattro, который, я думаю, должен быть 24 (я не говорю по-итальянски ...), но результат был 244.
добавлено автор Periodic Maintenance, источник
Python
Python
7 654 участник(ов)

Уютный чат для профессионалов, занимающихся поиском питоньих мудростей. Как не получить бан: https://t.me/ru_python/577926

Python beginners
Python beginners
4 449 участник(ов)

Вопросы про Python для чайников. Cпам и троллинг неприемлем. Не злоупотребляйте стикерами. Частозадаваемые вопросы: https://github.com/ru-python-beginners/faq/blob/master/README.md Статистика тут: https://grstats.me/chat/x4qym2k5uvfkr3al6at7

pro.python
pro.python
1 090 участник(ов)

Сообщество разработчиков под Python Создатель: @rodgelius

Rude Python
Rude Python
971 участник(ов)

Python без „девочек”, здесь матерятся и унижают Django. Not gay friendly. Правила: t.me/rudepython/114107 @rudepython | t.me/rudepython

rupython
rupython
509 участник(ов)

Группа создана с целью оперативного получения ответов на возникающие вопросы по разработке на яп python, смежные темы, а также человеческого общения. Приветствую!

Python-programming
Python-programming
266 участник(ов)

Чат группы вконтакте https://vk.com/python_community