我在python3中遇到了Unicode问题,而且我似乎不明白为什么会这样。
symbol= "ῇ̣"
print(len(symbol))
>>>>2
这封信来自一个单词:ἐ̣ν̣τ̣ῇ̣[αὐτ]ῇ,在这里我结合了变音标记。我想在Python 3中进行统计分析并将结果存储在数据库中,事实是我还在文本中存储了字符的位置(索引)。数据库应用程序正确地将示例中的符号变量视为一个字符,而Python将其视为两个-从而删除了整个索引。
该项目要求我保留变音符号,因此我不能简单地忽略它们或在字符串上进行.replace("combining diacritical mark","")
。
由于Python3将unicode作为字符串的默认设置,因此我对此有些傻眼。
我曾尝试使用希腊语重音https://pypi.org/project/greek-accentuation/中的base()
,strip()
和strip_length()
方法,但这无济于事。
项目要求是:
这是此项目的简化代码:
# -*- coding: utf-8 -*-
import csv
from alphabet_detector import AlphabetDetector
ad = AlphabetDetector()
with open("tbltext.csv", "r", encoding="utf8") as txt:
data = csv.reader(txt)
for row in data:
text = row[1]
### Here I have some string manipulation (lowering everything, replacing the predefined set of strings by equal-length '-',...)
###then I use the ad-module to detect the language by looping over my characters, this is where it goes wrong.
for letter in text:
lang = ad.detect_alphabet(letter)
如果我使用单词:ἐ̣ν̣τ̣ῇ̣[αὐτ]ῇ
作为forloop的示例;我的结果是:
>>> word = "ἐ̣ν̣τ̣ῇ̣[αὐτ]ῇ"
>>> for letter in word:
... print(letter)
...
ἐ
̣
ν
̣
τ
̣
ῇ
̣
[
α
ὐ
τ
]
ῇ
如何使Python将带有组合变音标记的字母视为一个字母,而不是使其分别打印字母和变音标记?
答案 0 :(得分:1)
该字符串的长度为2,所以这是正确的:两个代码点:
>>> list(hex(ord(c)) for c in symbol)
['0x1fc7', '0x323']
>>> list(unicodedata.name(c) for c in symbol)
['GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI', 'COMBINING DOT BELOW']
因此,您不应使用len
来计算字符。
您可以算出非组合字符,所以:
>>> import unicodedata
>>> len(''.join(ch for ch in symbol if unicodedata.combining(ch) == 0))
1
发件人:How do I get the "visible" length of a combining Unicode string in Python?(但我将其移植到python3)。
但这也不是最佳解决方案,具体取决于计算字符的范围。我认为在您的情况下就足够了,但是字体可以将字符合并为连字。在某些语言上,它们是视觉上新的字符(并且有很大不同)(并且不像西方语言中的连字)。
最后一条评论:我认为您应该规范化字符串。使用上面的代码,在这种情况下并不重要,但是在其他情况下,您可能会得到不同的结果。尤其是如果有人使用战斗性字符(例如,以mu为单位,或使用Eszett代替真正的希腊字符)。