2014-08-28 3 views
0

Существует много вопросов о python и unicode/string. Однако ни один из ответов не работает для меня.Преобразование символов не ascii в ascii из dictreader

Во-первых, файл открывается с использованием DictReader, затем каждая строка помещается в массив. Затем значение dict отправляется для преобразования в unicode.

Шаг Один получает данные

f = csv.DictReader(open(filename,"r") 
data = [] 
for row in f: 
    data.append(row) 

Шаг второй получает значение строки из Dict и замены акцентов (найдено это от других сообщений)

s = data[i].get('Name') 
strip_accents(s) 

def strip_accents(s): 
    try: s = unicode(s) 
    except: s = s.encode('utf-8') 
    s = unicodedata.normalize('NFKD', s).encode('ascii','ignore') 
    return s 

Я использую и попробовать за исключением того, что у некоторых строк есть акценты, другие - нет. То, что я не могу понять, что unicode(s) работает с type str, который не имеет акцентов, однако, когда type str имеет акцентов, он не

UnicodeDecodeError: 'ascii' codec can't decode byte 0xfc in position 11: ordinal not in range(128) 

я видел сообщения на этом, но ответы не работают. Когда я использую тип (ы), он говорит, что это <type 'str'>. Так что я попытался прочитать файл как юникодом

f = csv.DictReader(codecs.open(filename,"r",encoding='utf-8')) 

Но как только он идет читать

data = [] 
for row in f: 
    data.append(row) 

Эта ошибка возникает:

File "F:...files.py", line 9, in files 
    for row in f: 
    File "C:\Python27\lib\csv.py", line 104, in next 
    row = self.reader.next() 
    File "C:\Python27\lib\codecs.py", line 684, in next 
    return self.reader.next() 
    File "C:\Python27\lib\codecs.py", line 615, in next 
    line = self.readline() 
    File "C:\Python27\lib\codecs.py", line 530, in readline 
    data = self.read(readsize, firstline=True) 
    File "C:\Python27\lib\codecs.py", line 477, in read 
    newchars, decodedbytes = self.decode(data, self.errors) 
UnicodeDecodeError: 'utf8' codec can't decode byte 0xfc in position 0: invalid start byte 

Является ли эта ошибка вызвана тем, как dictreader обрабатывает юникод? Как обойти это?


Другие тесты.Как @univerio отметил, один элемент, который является причиной сбоя является ISO-8859-1

Изменения открытого заявления на:

f = csv.DictReader(codecs.open(filename,"r",encoding="cp1252")) 

производит несколько иной ошибку:

File "F:...files.py", line 9, in files 
    for row in f: 
    File "C:\Python27\lib\csv.py", line 104, in next 
    row = self.reader.next() 
UnicodeEncodeError: 'ascii' codec can't encode character u'\xfc' in position 11: ordinal not in range(128) 

Использования базовая открытая заявка и модификация strip_accents(), такие как:

печатает, что тип до сих пор ул и ошибки на

s = unicodedata.normalize('NFKD', s).encode('ascii','ignore') 
TypeError: must be unicode, not str 

на основе Python: Converting from ISO-8859-1/latin1 to UTF-8 изменения в

s = unicode(s.decode("iso-8859-1").encode('utf8')) 

производит различные ошибки:

except: s = unicode(s.decode("iso-8859-1").encode('utf8')) 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 11: ordinal not in range(128) 
+0

Это значит, что у вас плохие данные. Вы уверены, что ваш файл кодируется UTF-8? '0xFC' не является первым байтом любой допустимой последовательности UTF-8. (См. [Здесь] (http://en.wikipedia.org/wiki/UTF-8#Description).) – univerio

+0

@univerio это терпит неудачу с этим именем Thomas C. Südhof ... это из файла csv на окнах, и предположил его utf-8. Но, возможно, это было плохое предположение. Как я могу проверить все типы, так как существуют разные имена с разными символами. – user1938107

+0

Я имел в виду, что когда вы открываете файл с 'encoding = 'utf-8'', python не может декодировать первый байт файла, потому что он не является действительный первый байт в последовательности UTF-8. Похоже, что ваш файл может быть закодирован в Windows 1252, так как '0xFC' является шестнадцатеричным значением umlaut. Попробуйте открыть его с помощью 'encoding = 'cp1252". – univerio

ответ

1

Я думаю, что это должно работать:

def strip_accents(s): 
    s = s.decode("cp1252") # decode from cp1252 encoding instead of the implicit ascii encoding used by unicode() 
    s = unicodedata.normalize('NFKD', s).encode('ascii','ignore') 
    return s 

причина открытие файла с правильной кодировкой не помогло, потому что DictReader, похоже, не корректно обрабатывает строки Unicode.

+0

это сработало безупречно. – user1938107

Смежные вопросы