在日语中,存在适用于某些假名的变音标记,因此说“か”( 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) ),这也是为什么如果有一种“自然”的方式来做这件事会很好。
答案 0 :(得分:2)
您可以通过使用unicodedata.normalize()
function
>>> 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]