有没有办法在日语假名字符与不同的变音符号之间进行“逻辑”转换?

时间:2016-04-09 18:36:29

标签: python python-3.x unicode utf-8

在日语中,存在适用于某些假名的变音标记,因此说“か”( ka )和“が”之间存在逻辑关系( ga ) - 发出 ga 字符。

我想知道是否有任何自然的方式(在Python中,最好,虽然关于unicode的一般化答案也很好)做相当于将浊音字符转换为它们的清音等价物,反之亦然 - 相似之处到适用于拉丁文脚本的lower()方法。我正在寻找的一个例子:

>>> devoice('が')
"か"
>>> voice('か')
"が"
>>> devoice('か')
"か"
>>> semivoice('は')
"ぱ"
>>> devoice('ぱ')
"は"

目前,我似乎能够想出的最佳方法是生成一个由行,列和发声索引的查找表,然后查找我拥有的字符并将其翻译为正确的方向。也就是说,我想知道是否有更自然的方式来做到这一点。

一个潜在的缺陷是,在我看来,unicode组合字符似乎不等于它们的单码点等价物:

>>> a = chr(0x304B) + chr(0x3099)
>>> b = chr(0x304C)
>>> print(a)
'が'
>>> print(b)
'が'
>>> a == b
False

我主要关注那些涉及变音符号的人,因为它似乎很容易检测和去除组合标记。

注意:我不确定我是否完全理解日语音韵,以了解(u)和的正确行为(vu - rare / assolete) ),这也是为什么如果有一种“自然”的方式来做这件事会很好。

1 个答案:

答案 0 :(得分:2)

您可以通过使用unicodedata.normalize() function

分解角色(从NFC移动到NFD表格)来取消发声
>>> import unicodedata
>>> print(ascii(unicodedata.normalize('NFD', '\u304c')))
'\u304b\u3099'

所以devoice()可以实现为:

def devoice(char):
    return unicodedata.normalize('NFD', char)[0]

如果发声总是添加\u3099(它看起来像),您只需将其添加到输入的假名并返回NFC组合正常形式:

def voice(char):
    return unicodedata.normalize('NFC', char + '\u3099')

看起来像semivoiced意味着您添加\u309a'

def semivoice(char):
    return unicodedata.normalize('NFC', char + '\u309a')

您可以使用unicodedata.decomposition()来测试是否存在分解:

import unicodedata

def voice(char):
    if not ('\u3041' <= char <= '\u3096') or len(char) > 1 or unicodedata.decomposition(char):
        return char
    return unicodedata.normalize('NFC', char + '\u3099')

def semivoice(char):
    if not ('\u3041' <= char <= '\u3096') or len(char) > 1 or unicodedata.decomposition(char):
        return char
    return unicodedata.normalize('NFC', char + '\u309a')

def devoice(char):
    if not ('\u3041' <= char <= '\u3096') or len(char) > 1 or not unicodedata.decomposition(char):
        return char
    return unicodedata.normalize('NFD', char)[0]