如何在Python中逐个字符拆分Unicode字符串?

9

我的网站支持多种印度语言,用户可以动态更改语言。当用户输入一些字符串值时,我需要将其拆分为单个字符。因此,我正在寻找一种通用的方法,适用于英语和一组选择的印度语言。我已经在各个网站上搜索过了,但似乎没有常见的处理该要求的方法。有特定于语言的实现(例如用于泰米尔语的Open-Tamil软件包实现了get_letters),但我找不到在考虑字形的情况下拆分或迭代Unicode字符串中的字符的通用方法。

我尝试的众多方法之一:

name = u'தமிழ்'
print name
for i in list(name):
  print i

#expected output
தமிழ்
த
மி
ழ்

#actual output
தமிழ்
த
ம
ி
ழ
்

#Here is another an example using another Indian language
name = u'हिंदी'
print name
for i in list(name):
  print i

#expected output
हिंदी
हिं
दी

#actual output
हिंदी
ह
ि  
ं 
द
ी
3个回答

10
要实现“用户感知”的字符,无论是什么语言,都可以使用\X扩展字形群集)正则表达式:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import regex # $ pip install regex

for text in [u'தமிழ்', u'हिंदी']:
    print("\n".join(regex.findall(r'\X', text, regex.U)))

输出

த
மி
ழ்
हिं
दी

8
解决这个问题的方法是将所有"L"类字符与其后续的"M"类字符分组:
>>> regex.findall(ur'\p{L}\p{M}*', name)
[u'\u0ba4', u'\u0bae\u0bbf', u'\u0bb4\u0bcd']
>>> for c in regex.findall(ur'\p{L}\p{M}*', name):
...   print c
... 
த
மி
ழ்

regex


你好,你是指“regex”还是“re”?我尝试了“re.findall(ur'\p{L}\p{M}*', name)”但返回了一个空列表。 - user1928896
1
我的意思是“正则表达式”。这就是为什么我写了“正则表达式”,并包含了一个指向regex的链接。 - Ignacio Vazquez-Abrams
事实证明,我无法在我的应用程序引擎中使用regex模块,因为regex不是纯Python,而是包含了c扩展。是否有其他解决方案可以使用Python的re模块或其他方式来实现这一点? - user1928896
1
你需要使用 unicodedata.category() 来获取每个字符的类别,并相应地对它们进行分组。 - Ignacio Vazquez-Abrams
尽管在特定情况下这可能有效,但\X是提取单个字形簇的首选机制。 - tchrist
这个解决方案不正确。它无法处理组合表情符号,例如国旗。 - michau

2

uniseg非常适合此任务,文档也不错。虽然其他答案适用于国际Unicode字符,但如果用户输入表情符号,则无法正常工作。下面的解决方案 将会 有效:

>>> emoji = u''
>>> from uniseg.graphemecluster import grapheme_clusters
>>> for c in list(grapheme_clusters(emoji)):
...     print c
...




这是从pip install uniseg==0.7.1获得的信息。


我使用了 RegEx 2022.3.15 来测试你的表情符号,使用了 eXtended Graphemes \X,效果很好。看来 RegEx 已经进化了。 - Clemens Tolboom

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接