Python3 并结合变音符号

Python3 and combining Diacritics

我一直在 python3 中遇到 Unicode 问题,我似乎无法理解为什么会这样。

symbol= "ῇ̣"
print(len(symbol))
>>>>2

这封信来自一个词:ἐ̣ν̣τ̣ῇ̣[αὐτ]ῇ,我在其中组合了变音符号。我想在 Python 3 中进行统计分析并将结果存储在数据库中,问题是我还将字符的位置(索引)存储在文本中。数据库应用程序正确地将示例中的符号变量计为一个字符,而 Python 将其计为两个 - 丢弃整个索引。

该项目要求我保留变音符号,因此我不能简单地忽略它们或对字符串执行 .replace("combining diacritical mark","")

因为 Python3 将 unicode 作为字符串的默认值,我对此有点傻眼了。

我尝试使用希腊语重音的 base()strip()strip_length() 方法:https://pypi.org/project/greek-accentuation/ 但这也无济于事。

项目要求是:

这是这个项目的简化代码:

# -*- 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 将带有组合变音符号的字母视为一个字母,而不是分别打印字母和变音符号?

字符串的长度为 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

发件人:(但我将其移植到 python3)。

但这也不是最优解,具体取决于统计范围字符。我认为在您的情况下就足够了,但是字体可以将字符合并到 ligatures 中。在某些语言中,这些字符在视觉上是新的(并且非常不同)字符(与西方语言中的连字不同)。

作为最后一条评论:我认为您应该规范化字符串。使用上面的代码,在这种情况下没关系,但在其他情况下,您可能会得到不同的结果。特别是如果有人使用战斗性字符(例如单位 mu 或 Eszett,而不是真正的希腊字符)。