在Python 3中,计算泰语字符的位置

时间:2019-01-19 01:44:33

标签: python python-3.x unicode thai grapheme

第一,我使用了Python 3 grapheme库来解决我的问题。 (有关 grapheme 的更多信息,请参见this article)。但是令我感到惊讶的是,没有专用库,Python 3无法做到这一点……


我求助于 grapheme ,因为在许多网络搜索和阅读StackOverflow问题之后,我无法让Python 3按顺序返回正确数量的字符位置泰语字符。

例如,这是UTF-8泰文字符串:

thai_str = 'สีโชคดีเป็นสีชมพู สีโชคร้ายเป็นสีเหลืองและขาว'

我使用术语字符位置来标识一行泰文字符/字符串中的单个位置。这是因为字符位置可能包含泰国辅音,在某些情况下还包括该辅音上方或下方的元音或音调标记。辅音加上元音上方或下方的元音或音调标记在Unicode字符串中占据一个字符位置。 (某些泰国辅音字母的左侧,右侧或两侧可能还带有元音。这些元音占据了自己的角色位置。)

例如,按照从示例字符串生成的以下顺序,项目2和7是元音,项目10是音调标记。每个字符都使用UTF-8字符串中的单独字节,但不占用自己的字符位置。第3项和第8项是元音,位于辅音的左侧,因此占据字符位置。

01: ส
02: ี
03: โ
04: ช
05: ค
06: ด
07: ี
08: เ
09: ป
10: ็
...
45: ว

尝试确定示例字符串中的字符位置时,len(thai_str)返回45。这是不正确的。我能够获得正确数量的字符位置的唯一方法是使用grapheme.length(thai_str)来获得35

我还使用 encode 来获取以下信息:

b'\xe0\xb8\xaa\xe0\xb8\xb5\xe0\xb9\x82\xe0\xb8\x8a\xe0\xb8\x84\xe0\xb8\x94...

(计算似乎在每个泰语字符之前的xe0实例似乎并不正确……)

SO -在我的示例字符串中计算字符位置的唯一方法就是使用Python 3库,例如 grapheme

1 个答案:

答案 0 :(得分:4)

这不是唯一的方法,如果您想自己实现一个字素计数器,但是它很复杂,必须参考https://unicode.org规范才能正确使用。

thai_str不是UTF-8字符串,而是包含Unicode代码点的Unicode字符串。有不同的categories代码点。计数字符位置需要两个类别:

  • Lo Other_Letter ,其他字母,包括音节和表意文字;
  • Mn Nonspacing_Mark ,一个无间距的组合标记(零超前宽度)。

如果您跳过对 Nonpacing_Mark Mn)类代码点的计数,则可以大致看到字素库在做什么:

import unicodedata as ud

thai_str = 'สีโชคดีเป็นสีชมพู สีโชคร้ายเป็นสีเหลืองและขาว'

for cp in thai_str:
    print(f'{cp}\t{ud.category(cp)}\t{ud.name(cp)}')

print(sum(1 for cp in thai_str if ud.category(cp)[0] != 'M'))

输出:

ส   Lo  THAI CHARACTER SO SUA
ี   Mn  THAI CHARACTER SARA II
โ   Lo  THAI CHARACTER SARA O
ช   Lo  THAI CHARACTER CHO CHANG
ค   Lo  THAI CHARACTER KHO KHWAI
ด   Lo  THAI CHARACTER DO DEK
ี   Mn  THAI CHARACTER SARA II
เ   Lo  THAI CHARACTER SARA E
ป   Lo  THAI CHARACTER PO PLA
็   Mn  THAI CHARACTER MAITAIKHU
...
ว   Lo  THAI CHARACTER WO WAEN
35