我正在尝试打印单个字母,它可以正常使用英文和中文拼音但是当我尝试使用其他字母时,我也会使用unicode字符(Diacritic)
考虑这个词
महाभूकम्पले
当我尝试用键盘箭头键和它分开时空间这是महाभूकम्पले的结果,就像英文单词“示例”
一样E X A M P L E
म हा भू क म्प ले
现在,当我尝试运行python脚本以使用此代码自动执行此操作时
data= 'महाभूकम्पले'
index = 0
while index < len(data):
letter = data[index]
print (letter)
index = index + 1
我的结果是:(它已将所有变音符号分开)
म
ह
ा
भ
ू
क
म
्
प
ल
े
我需要的是这个
म
हा
भू
क
म्प
ले
答案 0 :(得分:2)
您的数据确实包含11个字符:
>>> data = 'महाभूकम्पले'
>>> len(data)
11
那是因为那里有几个变音字符,当打印时,它们与前面的字符组合在一起。您必须检测这些并将它们一起打印出来。
说起来容易做起来难。
Unicode数据库有各种拼写可以组合的字符的方法。在西方字母表中,您有像cedille(ç
上的卷曲)或重音符号或tremas(á
或ä
)这样的变音符号,在Unicode中可以表示为1和2字符,这些表单称为规范组合正常形式和规范分解正常形式,您可以使用unicodedata.normalize()
function在两种形式之间进行转换。< / p>
但是对于梵文剧本来说,没有复合形式;变音符号总是单独指定。相反,对于这些字符,换行符记录在lb
表中;当需要插入换行符时应该如何处理这些。对于梵文变音符号,行为设置为CM
或组合标记。 Unicode Line Breaking Algorithm中描述了确切含义。 CM
被描述为:
分类: CM
描述性名称:结合标记
示例:组合标记,控制代码
行为:禁止角色与前一个角色之间的换行符
问题是lb
模块无法提供unicodedata
数据表。
您必须使用LineBreaks.txt
table作为来源构建自己的表,然后测试该表中的下一个字符是否为CM
并将其打印在同一行上。
只提取CM
代码点:
cm_chars = set()
with open('LineBreak.txt') as lbtable:
for line in lbtable:
if ';CM' not in line:
continue
chars, category = line.partition(' ')[0].split(';')
if category != 'CM':
continue
chars = chars.split('..')
for codepoint in range(int(chars[0], 16), int(chars[-1], 16) + 1):
cm_chars.add(chr(codepoint))
然后使用它来检测是否要在同一行上打印下一个字符:
>>> data = 'महाभूकम्पले'
>>> index = 0
>>> while index < len(data):
... letters = data[index]
... while index + 1 < len(data) and data[index + 1] in cm_chars:
... letters += data[index + 1]
... index += 1
... print(letters)
... index += 1
...
म
हा
भू
क
म्
प
ले
但这只涵盖了CM字符。您可能还想要覆盖GL
(胶水)字符,这些字符附加到前面的和序列中的下一个字符。要获得更完整的解决方案,您需要构建一个no_linebreak(current, next)
函数,该函数将整个lb
表计入帐户,以确定两个字符之间是否存在换行符。
答案 1 :(得分:2)
快速解决方案(希望如此),而不是深入研究代码点语义(否则最好看看Martin的答案)。基于输出:
s = 'महाभूकम्पले'
for c in s:
print(c, unicodedata.category(c))
这是:
म Lo
ह Lo
ा Mc
भ Lo
ू Mn
क Lo
म Lo
् Mn
प Lo
ल Lo
े Mn
我们可以使用前面的代码点加入这些类别( Mc , Mn )中的代码点:
import unicodedata
from functools import reduce
def reducer(r, v):
if unicodedata.category(v) in ('Mc', 'Mn'):
r[-1] = r[-1] + v
else:
r.append(v)
return r
print(reduce(reducer, 'महाभूकम्पले', []))
输出对应于gedit
中的组合字符数:
['म', 'हा', 'भू', 'क', 'म्', 'प', 'ले']