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/ 但这也无济于事。
项目要求是:
- 检测属于字符的字母表(OK)
- 存储字符串位置(需要在数据库中突出显示)(NotOK)
- 能够处理多个 languages/alphabets 混合在一个字符串中。 (好)
- 遍历 CSV 输入。 (好)
- 忽略一组预定义字符串(确定)
- 忽略符合特定条件的字符串集(确定)
这是这个项目的简化代码:
# -*- 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,而不是真正的希腊字符)。
我一直在 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/ 但这也无济于事。
项目要求是:
- 检测属于字符的字母表(OK)
- 存储字符串位置(需要在数据库中突出显示)(NotOK)
- 能够处理多个 languages/alphabets 混合在一个字符串中。 (好)
- 遍历 CSV 输入。 (好)
- 忽略一组预定义字符串(确定)
- 忽略符合特定条件的字符串集(确定)
这是这个项目的简化代码:
# -*- 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
发件人:
但这也不是最优解,具体取决于统计范围字符。我认为在您的情况下就足够了,但是字体可以将字符合并到 ligatures 中。在某些语言中,这些字符在视觉上是新的(并且非常不同)字符(与西方语言中的连字不同)。
作为最后一条评论:我认为您应该规范化字符串。使用上面的代码,在这种情况下没关系,但在其他情况下,您可能会得到不同的结果。特别是如果有人使用战斗性字符(例如单位 mu 或 Eszett,而不是真正的希腊字符)。