Как мне лучше обрабатывать кодирование и декодирование с использованием символов Юникода и переходить от ASCII - PullRequest
1 голос
/ 25 февраля 2012

Я работаю над программой (Python 2.7), которая читает файлы xls (в формате MHTML).Одна из моих проблем заключается в том, что файлы содержат символы / символы, которые не являются символами ascii.Моим первоначальным решением было чтение файлов с использованием Unicode

. Вот как я читаю в файле:

theString=unicode(open(excelFile).read(),'UTF-8','replace')

Затем я использую lxml для некоторой обработки.В этих файлах много таблиц, первый шаг моей обработки требует, чтобы я нашел правильную таблицу.Я могу найти таблицу на основе слов, которые находятся в первой ячейке первого ряда.Это где становится сложно.Я надеялся использовать регулярное выражение для проверки text_content () ячейки, но обнаружил, что было слишком много вариантов слов (в тестовом прогоне из 3200 файлов я нашел 91 способ, которым концепция, определяющая только один изтаблицы были выражены. Поэтому я решил вывести все text_contents определенной ячейки и использовать некоторые алгоритмы в Excel для строгой идентификации всех вариантов.

Код, который я использовал для написания text_content (), был

 headerDict['header_'+str(column+1)]=encode(string,'Latin-1','replace')

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

Итак, я обработал метки / слова в Excel - преобразовал их все в нижний регистр, избавился от пробелов и сохранил вывод в виде текстового файла.

В текстовом файле есть столбец всех уникальныхспособы, которым таблица, которую я ищу, помечена

Я тогда читаю в файле - иВ первый раз, когда я прочитал это, используя

labels=set([label for label in unicode(open('C:\\balsheetstrings-1.txt').read(),'UTF-8','replace').split('\n')])

, я запустил свою программу и обнаружил, что некоторые совпадения не встречаются, исследуя ее, я обнаружил, что юникод заменил некоторые символы с \ ufffd, как в примере ниже

u'unauditedcondensedstatementsoffinancialcondition(usd\ufffd$)inthousands'

Дополнительные исследования показывают, что замена происходит, когда у юникода нет сопоставления для символа (вероятно, не точное объяснение, но это было моей интерпретацией)

Итак, я попытался (последумая, что я должен потерять) чтение в моем списке меток без использования Unicode.Поэтому я прочитал его, используя этот код:

labels=set(open('C:\\balsheetstrings-1.txt').readlines())

, теперь глядя на тот же ярлык в интерпретаторе, который я вижу

'unauditedcondensedstatementsoffinancialcondition(usd\xa0$)inthousands'

Затем я пытаюсь использовать этот набор ярлыков для сопоставления иЯ получаю эту ошибку

Warning (from warnings module):
File "C:\FunctionsForExcel.py", line 128
if tableHeader in testSet:
UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal

Теперь расстраивает то, что значение tableHeader НЕ находится в наборе тестов. Когда я спрашиваю значение tableHeader после того, как оно сломалось, я получил это

'fairvaluemeasurements:'

И чтобы добавить оскорбление травме, когда я набираю тест на холостом ходу

tableHeader in testSet

он правильно возвращает false

Я понимаю, что код '\ xa0' является кодом для неразрывногопространство.То же самое касается Python, когда я читал его без использования юникода.Я думал, что избавился от всех пробелов в Excel, но чтобы справиться с ними, я разделил их, а затем присоединился к ним

 labels=[''.joiin([word for word in label.split()] for label in labels])

Я до сих пор не получил вопрос.Извините, я все еще пытаюсь обдумать это.Мне кажется, что я имею дело с противоречивым поведением здесь.Когда я читал строку в оригинале и использовал Unicode и UTF-8, все символы были сохранены / переносимы, если хотите.Я закодировал их, чтобы записать их, и они отлично отображались в Excel, затем я сохранил их как текстовый файл, и они выглядели хорошо. Но что-то происходит, и я не могу понять, где.

Если яЯ мог бы избежать выписывания строк, чтобы определить правильные ярлыки. У меня есть ощущение, что моя проблема исчезнет, ​​но существует 20000 или более ярлыков.Я могу использовать регулярное выражение, чтобы значительно сократить свой потенциальный список, но некоторые из них просто требуют проверки.

В заключение отметим, что все исходные файлы указывают кодировку = 'UTF-8'

Напомним, когда я читаю sourcedocument и список меток при использовании Unicode, я не могу сделать некоторые совпадения, потому что метки имеют некоторые символы, замененные на ufffd, и когда я читаю sourcedocument при использовании Unicode и список меток без каких-либоспециальная обработка Я получаю предупреждение.

Я хотел бы понять, что происходит, чтобы я мог это исправить, но я исчерпал все места, которые я могу думать, чтобы посмотреть

Ответы [ 3 ]

2 голосов
/ 25 февраля 2012

Вы читаете (и пишете) закодированные файлы, например:

import codecs
# read a utf8 encoded file and return the data as unicode
data = codecs.open(excelFile, 'rb', 'UTF-8').read()

Используемая вами кодировка не имеет значения, если вы выполняете все сравнения в юникоде.

1 голос
/ 26 февраля 2012

Я понимаю, что код '\ xa0' является кодом для неразрывного пробела.

В строке байтов \xA0 - это байт, представляющий неразрывный пробелнесколько кодировок;наиболее вероятной из них будет кодовая страница Windows 1252 (западноевропейская).Но это определенно не UTF-8, где сам по себе байт \xA0 недопустим.

Используйте .decode('cp1252'), чтобы превратить эту строку байтов в Unicode вместо 'utf-8'.В общем, если вы хотите узнать, в какой кодировке находится HTML-файл, найдите параметр charset в теге <meta http-equiv="Content-Type">;вероятно, он будет отличаться в зависимости от того, что его экспортировало.

0 голосов
/ 25 февраля 2012

Не совсем решение, но что-то вроде xlrd , вероятно, имело бы гораздо больше смысла, чем прыгать через все эти обручи.

...