2012-12-28 50 views
2

我需要Python代碼才能將數字轉換爲意大利語和意大利語。將意大利語和意大利語轉換爲蟒碼數

回顧以前的問題,我瞭解到pynum2word在幾種語言中只有一種方式(num - > words),但唉,而不是意大利語。

如果在Python中不存在這樣的代碼,我不介意從Perl/Ruby/Java中翻譯這樣的代碼。

謝謝。

+0

如果您看一下pynum2word模塊的源代碼,爲什麼不用num2word_EN.py中的所有英文字符串替換它們的意大利語對應字符?這很冒險,但是你不必深入研究源代碼就能達到預期的效果。 – stib

+0

或者西班牙語模塊可能會接近意大利語。 –

回答

2

要做到從意大利轉換爲衆多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的東西。如果你不知道意大利語,我可能會試着幫忙寫。

+0

謝謝,這完美的作品!至於單詞的數字,最好直接將代碼添加到pynum2word中。再次感謝。 –

+0

...幾乎完美。我把我認爲應該是24(我不會說意大利語...)的ventiquattro,但結果是244. –

+0

嚴。你說得對,我現在試着解決這個問題。 – Bakuriu

相關問題