我需要Python代码才能将数字转换为意大利语和意大利语。将意大利语和意大利语转换为蟒码数
回顾以前的问题,我了解到pynum2word在几种语言中只有一种方式(num - > words),但唉,而不是意大利语。
如果在Python中不存在这样的代码,我不介意从Perl/Ruby/Java中翻译这样的代码。
谢谢。
我需要Python代码才能将数字转换为意大利语和意大利语。将意大利语和意大利语转换为蟒码数
回顾以前的问题,我了解到pynum2word在几种语言中只有一种方式(num - > words),但唉,而不是意大利语。
如果在Python中不存在这样的代码,我不介意从Perl/Ruby/Java中翻译这样的代码。
谢谢。
要做到从意大利转换为众多IT使用正则表达式很简单:
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:
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...'
,与(错误)的奇异milione
代替milioni
你:
>>> let2num('ventiquattromiliardicentotrentatremilionetredicimiladuecentouno')
'24.003.013.201'
这是不是“正确的”。但拼写其实是错误的。我相信milione
作为milioni
的准确synonim应该不会太难,或者添加一些错误检查,以便在发现拼写错误时会引发错误。请注意这一点。
至于调试上面的代码(如果你想改变)一个建议是添加一行:
print 'token:', token, 'current result:', result
由于for
循环的第一条指令。然后看看正在做什么,你应该能够识别代码背后的“推理”,并查看bug所在的位置。
我认为对于其他转换,可以很容易地实现基于pynum2word
的东西。如果你不知道意大利语,我可能会试着帮忙写。
谢谢,这完美的作品!至于单词的数字,最好直接将代码添加到pynum2word中。再次感谢。 –
...几乎完美。我把我认为应该是24(我不会说意大利语...)的ventiquattro,但结果是244. –
严。你说得对,我现在试着解决这个问题。 – Bakuriu
如果您看一下pynum2word模块的源代码,为什么不用num2word_EN.py中的所有英文字符串替换它们的意大利语对应字符?这很冒险,但是你不必深入研究源代码就能达到预期的效果。 – stib
或者西班牙语模块可能会接近意大利语。 –