在Python中删除字符串中的奇怪隐藏字符

3

我有一个CSV文件,其中一列包含字符串列表。似乎这些字符串中存在隐藏字符,只有当从每个字符串中删除某些字符时才能看到这些隐藏字符。

#string copied from column
print(len('kommunikationsfähigkeit'))
#same string entered by me 
print(len('kommunikationsfähigkeit'))

24
23

将列复制的字符串中的部分删除后,我得到了以下内容:

''̈igkeit'

有人知道那里出了什么问题吗?我尝试使用encoding='utf8'读取csv文件,但它没有改变任何东西。 我显然想要摆脱那些字符。


尝试打印“从列复制的字符串”的输出是什么?它也显示这些字符吗? - Vishakha Lall
1
你尝试过使用 .strip() 函数吗? - Mortz
它并没有起到作用!我需要摆脱它们,因为我想检查一个元素是否在那个列表中,如果我输入那个元素,它就无法识别它。 此外,尝试了.strip()但没有成功。 - Michael
请参考此处:https://dev59.com/xbjoa4cB1Zd3GeqPC7Kj - Shijith
2个回答

4

两者都是UTF-8编码,但这里有不同的方式来显示相同的视觉字符。第一个字符串包含U+00E4——带分音符的小写拉丁字母“a”(LATIN SMALL LETTER A WITH DIAERESIS)。而您的第二个字符串包含字母“a”后跟着U+0308——组合用分音符(COMBINING DIAERESIS) ( ̈ ),它们组合起来会被呈现为“ä”。

您可以使用unicodedata自行检查这些字符串:

import unicodedata

for c in string:
    print(unicodedata.name(c))

以上两种方式都是表示“ä”的有效方法,在适当的Unicode标准化下它们被视为等价。您可以使用unicodedata.normalize来规范不同的表示。例如,您可以将两个字符串转换为正常形式C(尽管第一个字符串已经在NFC中):

a = 'kommunikationsfähigkeit'
b = 'kommunikationsfähigkeit'
print(f'len(a) = {len(a)}')
# len(a) = 23
print(f'len(b) = {len(b)}')
# len(b) = 24
print(f'a == b: {a == b}')
# a == b: False

norm_a = unicodedata.normalize('NFC', a)
norm_b = unicodedata.normalize('NFC', b)
print(f'len(norm_a) = {len(norm_a)}')
# len(norm_a) = 23
print(f'len(norm_b) = {len(norm_b)}')
# len(norm_b) = 23
print(f'norm_a == norm_b: {norm_a == norm_b}')
# norm_a == norm_b: True

1
这是我不喜欢Unicode的原因之一。标准定义了多种表示字符的方式,而不是说“这是唯一正确的方式”。在这种情况下,一个字符串使用“组合”形式,而另一个字符串使用“分解”形式(单独的字母和分音符号)。
您可能需要考虑规范化数据:
import unicodedata
s1 = 'kommunikationsfähigkeit'
s2 = 'kommunikationsfähigkeit'
ns1 = unicodedata.normalize('NFC', s1)
ns2 = unicodedata.normalize('NFC', s2)
print(s1 == s2, ns1 == ns2)
# prints False True

上面的代码片段将字符串规范化为组合形式,这是许多系统使用的形式。分解形式通常出现在 macOS 系统中,因为那里是默认设置。您可以看到,这些字符串最初不被视为相等,但在规范化后它们就相等了。

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