【问题标题】:Is there a way to programmatically combine Korean unicode into one?有没有办法以编程方式将韩语 unicode 组合成一个?
【发布时间】:2017-07-17 16:50:40
【问题描述】:

使用韩语输入法编辑器 (IME),可以输入버리 + ,它会自动变为버려

有没有办法在 Python 中以编程方式做到这一点?

>>> x, y = '버리', '어'
>>> z = '버려'
>>> ord(z[-1])
47140
>>> ord(x[-1]), ord(y)
(47532, 50612)

有没有办法计算 47532 + 50612 -> 47140?

这里还有一些例子:

가보 + 아 -> 가봐

끝나 + ㄹ -> 끝날

【问题讨论】:

  • 字符之间的关系不是Unicode标准的一部分。
  • 正如彼得所说,Unicode 中没有这种关系。 Unicode 标准的唯一关系是单个 Jamo 字符和预先组合的韩文音节之间的关系;您可以将孤立的 jamo 组合成完整的音节。在这里,您想将两个音节 (리 + 어) 组合成一个不同的音节。您需要自己准备一张桌子(或在其他地方找到一张)。
  • @PeterWood:我认为他的问题更多是关于“是否有任何库已经处理了所有映射?”
  • Unicode 9.0 标准的第 18.6 节涵盖了韩文音节,这似乎描述了问题中的大部分代码点。它讨论了“jamo”和现代韩文音节的“Johab”集(399 个可能的两jamo 音节块和 10,773 个可能的三jamo 音节块)。它引用了第 3.12 节 Conjoining Jame Behavior。这看起来像一个复杂的领域。 (您可能知道,您可以在Unicode 网站上找到这些章节。)
  • @JonathanLeffler:这可能就是为什么这个问题被表述为“有没有办法以编程方式将韩语 unicode 组合成一个?” =)

标签: python unicode nlp ime korean-nlp


【解决方案1】:

我是韩国人。首先,如果你输入버리 + ,它会变成버리어而不是버려버려버리어 的缩写,不是自动生成的。同样的原因,가보아 在打字过程中也不能自动变为가봐

其次,相比之下,끝나 + 变为 끝날,因为 没有 jongseong(종성)。请注意,韩文的一个字符由 choseong(초성)、jungseong(중성) 和 jongseong 组成。 choseongjongseong 是辅音,jungseong 是元音。在Wikipedia 上查看更多信息。所以只有在打字的时候没有jongseong(比如끝나),才有可能有jongseong(ㄹ)。

如果你想把버리 + 变成버려,你应该实现一些韩语语法,特别是对于这种情况,jungseong的缩写。例如 + = , + = 如您提供的那样。 한글 맞춤법 chapter 4. section 5(我现在找不到英文页面)这样定义缩写。这是可能的,但不是那么容易的工作,尤其是对于非韩国人。

接下来,如果你想要的只是将끝나 + 变成끝날,这可能是一个相对容易的工作,因为有一些库可以处理chosong em>,钟声钟声。如果是 Python,我找到了hgtk。你可以这样试试(非实用代码):

# hgtk methods take one character at a time
cjj1 = hgtk.letter.decompose('나')  # ('ㄴ', 'ㅏ', '')
cjj2 = hgtk.letter.decompose('ㄹ')  # ('ㄹ', '', '')
if cjj1[2]) == '' and cjj2[1]) == '':
    cjj = (cjj1[0], cjj1[1], cjj2[0])
    cjj2 = None

不过,如果没有适当的韩文知识,将很难完成。

【讨论】:

  • 感谢@SangbokLee 的解释!!
【解决方案2】:

您可以使用自己的翻译表。
缺点是您必须手动输入所有配对,或者您有一个文件可以从中获取它。
例如:

# Sample Korean chars to map
k = [[('버리', '어'), ('버려')], [('가보', '아'), ('가봐')], [('끝나', 'ㄹ'), ('끝날')]]

class Korean(object):
    def __init__(self):
        self.map = {}

        for m in k:
            key = m[0][0] + m[0][1]
            self.map[hash(key)] = m[1]

    def __getitem__(self, item):
        return self.map[hash(item)]

    def translate(self, s):
        return [ self.map[hash(token)] for token in s]

if __name__ == '__main__':
    k_map = Korean()
    k_chars = [ m[0][0] + m[0][1] for m in  k]

    print('Input: %s' % k_chars)
    print('Output: %s' % k_map.translate(k_chars))

    one_char_3 = k[0][0][0] + k[0][0][1]
    print('%s = %s' % (one_char_3, k_map[ one_char_3 ]) )

输入:['버리어', '가보아', '끝나ㄹ']
输出:['버려', '가봐', '끝날']
버리어 = 버려

用 Python:3.4.2 测试

【讨论】:

  • 这是不切实际的,因为韩文的组合数量非常多。
  • 我指出了这一点。多大,说一下数量。多想想字典,世界上所有的字典都是手工写的。其中一个,左边或右边,应该已经存在。所以这只是一半的工作要做。给出的样本是无序的,我认为有序的样本会显示出数学相关性。
  • 有关详细信息,请参阅我的答案中的 Wikipedia 链接。号码是1,638,394(韩文页面)。
  • 该数字基于 Unicode。如果你使用相当旧的子字符集,它可以减少,但仍然不实用。
猜你喜欢
  • 2019-06-17
  • 2015-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多