удалить странные скрытые символы из строки в Python - PullRequest
2 голосов
/ 17 января 2020

У меня есть CSV-файл со столбцом, содержащим списки строк. Кажется, что эти строки имеют скрытые символы, которые я вижу только при удалении определенных символов из каждой строки.

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

24
23

при удалении частей скопированной строки столбца, я получаю это:

''̈igkeit'

Кто-нибудь знает, что там происходит? Я попытался прочитать csv с encoding = 'utf8', но это ничего не изменило. Я, очевидно, хочу избавиться от этих персонажей.

Ответы [ 2 ]

3 голосов
/ 17 января 2020

Оба формата UTF-8, но существуют разные способы визуализации одного и того же визуального символа. Первая строка содержит U + 00E4 - ЛАТИНСКОЕ МАЛЕНЬКОЕ ПИСЬМО A С ДИАРЕЗОМ . Ваша вторая строка содержит «a», за которым следует U + 0308 - ДИАЭРЕС КОМБИНИРОВАНИЯ (̈), который в сочетании отображается как «ä».

Вы можете проверить строки самостоятельно, используя unicodedata :

import unicodedata

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

Оба вышеперечисленных являются допустимыми способами представления «ä» и считаются эквивалентными при подходящей нормализации Unicode. Вы можете использовать unicodedata.normalize для нормализации различных представлений. Например, вы можете преобразовать обе строки в обычную форму C (хотя первая из них уже находится в NF C):

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 голос
/ 17 января 2020

Это одна из причин, по которой мне не нравится 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, так как она используется по умолчанию. Вы можете видеть, что строки изначально не сравниваются как равные, но они сравниваются после нормализации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...