2017-11-14 4 views
0

私はカタカナとひらがなの間で変換二つの機能を持っており、彼らは同じように見える:ひらがなとカタカナを変換する2つの同様の関数を組み合わせるにはどうすればよいですか?

katakana_minus_hiragana = 0x30a1 - 0x3041 # KATAKANA LETTER A - HIRAGANA A 

def is_hirgana(char): 
    return 0x3040 < ord(char[0]) and ord(char[0]) < 0x3097 

def is_katakana(char): 
    return 0x30a0 < ord(char[0]) and ord(char[0]) < 0x30f7 

def hiragana_to_katakana(hiragana_text): 
    katakana_text = "" 
    max_len = 0 
    for i, char in enumerate(hiragana_text): 
     if is_hirgana(char): 
      katakana_text += chr(ord(char) + katakana_minus_hiragana) 
      max_len += 1 
     else: 
      break 
    return katakana_text, max_len 

def katakana_to_hiragana(katakana_text): 
    hiragana_text = "" 
    max_len = 0 
    for i, char in enumerate(katakana_text): 
     if is_katakana(char): 
      hiragana_text += chr(ord(char) - katakana_minus_hiragana) 
      max_len += 1 
     else: 
      break 
    return hiragana_text, max_len 

アヒル型機能やスーパー/メタ関数にhiragana_to_katakana()katakana_to_hiragana()を簡素化する方法はありますか?

など。何かのように

def convert_hk_kh(text, charset_range, offset): 
    charset_start, charset_end = charset_range 
    output_text = "" 
    max_len = 0 
    for i, char in enumerate(text): 
     if charset_start < ord(char[0]) and ord(char[0]) < charset_end: 
      output_text += chr(ord(char) + offset) 
      max_len +=1 
     else: 
      break 
    return output_text, max_len 


def katakana_to_hiragana(katakana_text): 
    return convert_hk_kh(katakana_text, (0x30a0, 0x30f7), -katakana_minus_hiragana) 


def hiragana_to_katakana(hiragana_text): 
    return convert_hk_kh(hiragana_text, (0x3040, 0x3097), katakana_minus_hiragana) 

非常に似ている2つの機能を単純化するために他のpythonic方法はありますか?

EDITED

str.translateと同じことをしているようだhttps://github.com/olsgaard/Japanese_nlp_scriptsもあります。それはより効率的ですか?もっとpythonic?

+0

あなたはORD(CHAR [0]) Sraw

+0

はい、 'str.translate'は1のため、より効率的かつ神託である

答えて

1

私はこのような何かしたい:

KATAKANA_HIRGANA_SHIFT = 0x30a1 - 0x3041 # KATAKANA LETTER A - HIRAGANA A 

def shift_chars_prefix(text, amount, condition): 
    output = '' 

    for last_index, char in enumerate(text): 
     if not condition(char): 
      break 

     output += chr(ord(char) + amount) 

    return output, last_index 

def katakana_to_hiragana(text): 
    return shift_chars_prefix(text, -KATAKANA_HIRGANA_SHIFT, lambda c: '\u30a0' < c < '\u30f7') 

def hiragana_to_katakana(text): 
    return shift_chars_prefix(text, KATAKANA_HIRGANA_SHIFT, lambda c: '\u3040' < c < '\u3097') 

あなたが交換さプレフィックスの長さが返されない場合にも、正規表現を使用することができます。

import re 

KATAKANA_HIRGANA_SHIFT = 0x30a1 - 0x3041 # KATAKANA LETTER A - HIRAGANA A 

def shift_by(n): 
    def replacer(match): 
     return ''.join(chr(ord(c) + n) for c in match.group(0)) 

    return replacer 

def katakana_to_hiragana(text): 
    return re.sub(r'^[\u30a1-\u30f6]+', shift_by(KATAKANA_HIRGANA_SHIFT), text) 

def hiragana_to_katakana(text): 
    return re.sub(r'^[\u3041-\u3096]+', shift_by(-KATAKANA_HIRGANA_SHIFT), text) 
+0

そして 'shift_by(n)'は単純なシーザー暗号ですか? – alvas

+1

@alvas: 'shift_by(n)'は 'SRE_Match'を取り込んで' n 'だけシフトする関数を作成します。それは 'SRE_Match'オブジェクトを受け入れるだけなので、シーザー暗号関数のように汎用的ではありません。 – Blender

1

ここで切り替えます機能だがそれぞれの種類のかなは互いに 与えられた関数とは違って、 の非カナに遭遇したときに停止するのではなく、単に を変更せずにこれらの文字を渡します。

カナタイプ間の変換はこれほど簡単ではないことに注意してください。 例では、ひらがなの中で、長い「e」音はええまたはえい (たとえばおねえ姉妹、せんせい先生)で示され、カタカナでは はchōonpu(オネー、せんせーー)を使用します。あなたが使用する の範囲外にかな文字があります。

def switch_kana_type(kana_text): 
    """Replace each kind of kana with the other kind. Other characters are 
    passed through unchanged.""" 

    output_text = '' 
    for c in kana_text: 
     if is_hiragana(c): # Note typo fix of "is_hirgana" 
      output_text += chr(ord(c) + katakana_minus_hiragana) 
     elif is_katakana(char): 
      output_text += chr(ord(c) - katakana_minus_hiragana) 
     else: 
      output_text += c; 
    return output_text, len(output_text) 
関連する問題