按字符拆分泰语文本

2024-04-20 02:54:08 发布

您现在位置:Python中文网/ 问答频道 /正文

不是用词的界限,这是可以解决的。在

示例:

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

这会产生:

十一






十一

十一

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

文本的可移植表示是:

^{pr2}$

Tags: textin文本env示例forbinusr
3条回答

为了澄清前面的答案,您遇到的问题是缺少的字符是“组合字符”(元音和音调符号必须与其他字符组合才能正确显示)。没有标准的方式来显示这些字符本身,尽管最常见的惯例是使用虚线圆圈作为空辅音,如Serge Ballesta的答案所示。在

问题是,对于你的应用程序,每个元音和变音符号都被视为一个单独的字符,还是像Serge的答案那样用“print cell”来分隔?在

顺便说一句,在正常使用中,除了在键入一个较长的单词的过程中,不应该在没有后续辅音的情况下显示主元音SARA E和SARA AE。在

有关更多信息,请参阅泰国API联盟(TAPIC)发布的wtt2.0标准,该标准定义了如何组合、显示字符以及如何处理错误。在

我不能完全重现,但这里有一个稍微修改过的脚本版本,在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个字符,也就是说,如果您不想分解组合字符,并且没有其他应考虑的组合规则,则可以使用类似以下内容:

^{pr2}$

这样的话:

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

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

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

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

考虑一下字母è。让s和{}在Python shell中等于è

^{pr2}$

同一封信?对一个说法语的人来说,是的。对于计算机,不:

>>> 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', '̀']

字符串中有几个组合字符。因此,对于Python来说,9个字符的泰语字符串变成了13个字符的字符串。在

法语的解决方案是基于Unicode equivalence规范化字符串:

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

但这对许多非拉丁语言来说并不奏效。处理unicode字符串(可能是组成single grapheme的多个代码点)的一个简单方法是使用一个regex引擎,该引擎通过支持\X正确地处理这一问题。不幸的是,Python还包括re模块doesn't。在

建议的替代品regex确实支持\X,但是:

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

相关问题 更多 >