按字符拆分泰语文本

时间:2015-05-07 14:26:21

标签: python python-3.x unicode thai

不是通过字边界,这是可以解决的。

示例:

#!/usr/bin/env python3  
text = 'เมื่อแรกเริ่ม'  
for char in text:  
    print(char)  

这产生:






这显然不是理想的输出。有什么想法吗?

文本的可移植表示是:

text = u'\u0e40\u0e21\u0e37\u0e48\u0e2d\u0e41\u0e23\u0e01\u0e40\u0e23\u0e34\u0e48\u0e21'

3 个答案:

答案 0 :(得分:8)

tl; dr:使用\X正则表达式提取用户感知的字符:

>>> import regex # $ pip install regex
>>> regex.findall(u'\\X', u'เมื่อแรกเริ่ม')
['เ', 'มื่', 'อ', 'แ', 'ร', 'ก', 'เ', 'ริ่', 'ม']

虽然我不懂泰语,但我知道一点法语。

考虑字母è。在Python shell中让ss2等于è

>>> s
'è'
>>> s2
'è'

同一封信? oui,以视觉上的法语发言人。对于计算机,没有:

>>> s==s2
False

您可以使用è的实际代码点创建相同的字母,也可以使用字母e并添加添加该重音字符的组合代码点。他们有不同的编码:

>>> s.encode('utf-8')
b'\xc3\xa8'
>>> s2.encode('utf-8')
b'e\xcc\x80'

不同长度:

>>> len(s)
1
>>> len(s2)
2

但在视觉上,两种编码都会产生字母' è。这称为grapheme,或最终用户认为的一个字符。

您可以演示您所看到的相同循环行为:

>>> [c for c in s]
['è']
>>> [c for c in s2]
['e', '̀']

您的字符串中包含多个组合字符。因此,你眼中的9字形字符泰语字符串成为Python的13个字符串。

法语解决方案是根据Unicode equivalence标准化字符串:

>>> from unicodedata import normalize
>>> normalize('NFC', s2) == s
True

但这对许多非拉丁语言不起作用。处理组成single grapheme的多个代码点的unicode字符串的简单方法是使用正则表达式引擎,通过支持\X来正确处理此问题。不幸的是,Python还包括re模块doesn't

建议的替换regex确实支持\X

>>> import regex
>>> text = 'เมื่อแรกเริ่ม'
>>> regex.findall(r'\X', text)
['เ', 'มื่', 'อ', 'แ', 'ร', 'ก', 'เ', 'ริ่', 'ม']
>>> len(_)
9

答案 1 :(得分:2)

我无法完全重现,但这里是您脚本的略微修改版本,在Windows7 64系统上的IDLE 3.4输出:

>>> for char in text:
    print(char, hex(ord(char)), unicodedata.name(char),'-',
          unicodedata.category(char), '-', unicodedata.combining(char), '-',
          unicodedata.east_asian_width(char))


เ 0xe40 THAI CHARACTER SARA E - Lo - 0 - N
ม 0xe21 THAI CHARACTER MO MA - Lo - 0 - N
ื 0xe37 THAI CHARACTER SARA UEE - Mn - 0 - N
่ 0xe48 THAI CHARACTER MAI EK - Mn - 107 - N
อ 0xe2d THAI CHARACTER O ANG - Lo - 0 - N
แ 0xe41 THAI CHARACTER SARA AE - Lo - 0 - N
ร 0xe23 THAI CHARACTER RO RUA - Lo - 0 - N
ก 0xe01 THAI CHARACTER KO KAI - Lo - 0 - N
เ 0xe40 THAI CHARACTER SARA E - Lo - 0 - N
ร 0xe23 THAI CHARACTER RO RUA - Lo - 0 - N
ิ 0xe34 THAI CHARACTER SARA I - Mn - 0 - N
่ 0xe48 THAI CHARACTER MAI EK - Mn - 107 - N
ม 0xe21 THAI CHARACTER MO MA - Lo - 0 - N
>>>

我真的不知道这些角色是什么 - 我的泰语非常差:-) - 但它表明:

  • 文本被认为是泰语......
  • 输出与len(text)13
  • 一致
  • 类别和组合在组合字符时是不同的

如果是预期输出,则证明您的问题不在Python中,而是在显示它的控制台上有更多问题。您应该尝试将输出重定向到文件,然后在支持泰语字符的unicode编辑器中打开该文件。

如果预期的输出只有9个字符,那就是如果你不想分解组合字符,并且如果没有其它组合规则应该考虑,你可以使用类似的东西:

def Thaidump(t):
    old = None
    for i in t:
        if unicodedata.category(i) == 'Mn':
            if old is not None:
                old = old + i
        else:
            if old is not None:
                print(old)
            old = i
    print(old)

那样:

>>> Thaidump(text)
เ
มื่
อ
แ
ร
ก
เ
ริ่
ม
>>> 

答案 2 :(得分:2)

为了澄清之前的答案,您遇到的问题是缺少的字符是“组合字符” - 元音和变音符号必须与其他字符组合才能正确显示。没有标准的方法可以自己显示这些字符,尽管最常见的惯例是使用虚线圆作为空辅音,如Serge Ballesta的回答所示。

那么问题是,对于你的应用程序,每个元音和变音符被认为是一个单独的字符,或者你是否希望用“印刷单元”分开,如Serge的回答所示?

顺便说一下,在正常使用情况下,除了在输入更长的单词的过程中,不应在没有辅助辅音的情况下显示主元音SARA E和SARA AE。

有关更多信息,请参阅Thai API Consortium(TAPIC)发布的WTT 2.0标准,该标准定义了如何组合,显示字符以及如何处理错误。

相关问题