首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >按字符分割泰文

按字符分割泰文
EN

Stack Overflow用户
提问于 2015-05-07 14:26:20
回答 3查看 3.9K关注 0票数 8

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

示例:

代码语言:javascript
复制
#!/usr/bin/env python3  
text = 'เมื่อแรกเริ่ม'  
for char in text:  
    print(char)  

这就产生了:

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

可移植的文本表示是:

代码语言:javascript
复制
text = u'\u0e40\u0e21\u0e37\u0e48\u0e2d\u0e41\u0e23\u0e01\u0e40\u0e23\u0e34\u0e48\u0e21'
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-05-07 15:41:02

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

代码语言:javascript
复制
>>> import regex # $ pip install regex
>>> regex.findall(u'\\X', u'เมื่อแรกเริ่ม')
['เ', 'มื่', 'อ', 'แ', 'ร', 'ก', 'เ', 'ริ่', 'ม']

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

以字母è为例。让ss2在Python中等于è

代码语言:javascript
复制
>>> s
'è'
>>> s2
'è'

同一封信?对说法语的人来说,是的。对电脑来说,不:

代码语言:javascript
复制
>>> s==s2
False

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

代码语言:javascript
复制
>>> s.encode('utf-8')
b'\xc3\xa8'
>>> s2.encode('utf-8')
b'e\xcc\x80'

和不同的净长度:

代码语言:javascript
复制
>>> len(s)
1
>>> len(s2)
2

但从视觉上看,这两种编码都会产生“字母”è。这被称为字素,或最终用户所认为的一个字符。

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

代码语言:javascript
复制
>>> [c for c in s]
['è']
>>> [c for c in s2]
['e', '̀']

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

法语的解决方案是基于Unicode 等价性规范字符串。

代码语言:javascript
复制
>>> from unicodedata import normalize
>>> normalize('NFC', s2) == s
True

然而,对于许多非拉丁语来说,这是行不通的。处理构成单字素的多个代码点的unicode字符串的一种简单方法是使用regex引擎,该引擎通过支持\X正确地处理此问题。不幸的是,Python还包括re模块不会

不过,拟议中的替代方案regex确实支持\X

代码语言:javascript
复制
>>> import regex
>>> text = 'เมื่อแรกเริ่ม'
>>> regex.findall(r'\X', text)
['เ', 'มื่', 'อ', 'แ', 'ร', 'ก', 'เ', 'ริ่', 'ม']
>>> len(_)
9
票数 11
EN

Stack Overflow用户

发布于 2015-05-07 14:59:00

我不能完全复制,但是下面是您脚本的一个稍微修改的版本,它的输出在Windows7 64系统上的空闲3.4上:

代码语言:javascript
复制
>>> 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个字符,也就是说,如果您不想对组合字符进行分解,并且如果没有其他应该考虑的组合规则,则可以使用以下内容:

代码语言:javascript
复制
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)

这条路:

代码语言:javascript
复制
>>> Thaidump(text)
เ
มื่
อ
แ
ร
ก
เ
ริ่
ม
>>> 
票数 3
EN

Stack Overflow用户

发布于 2017-07-20 13:34:01

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

那么问题是,对于您的应用程序来说,每个元音和双字母都被认为是一个单独的字符,还是像Serge的答案中所示的那样,您希望用“打印单元格”来分隔?

顺便说一句,在正常用法中,除了输入一个较长的单词的过程中,不应该在没有以下辅音的情况下显示铅元音SARA和SARA。

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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30103965

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档