Как исключить U+2028 из разделителей строк в Python при чтении файла?
У меня есть файл в UTF-8, где некоторые строки содержат символ разделителя строк U+2028 (http://www.fileformat.info/info/unicode/char/2028/index.htm я не хочу, чтобы это рассматривалось как разрыв строки, когда я читаю строки из файла. Есть ли способ исключить его из разделителей, когда я перебираю файл или использую readlines ()? (Кроме чтения всего файла в строку и последующего разбиения на n.) спасибо!
5 ответов:
Я не могу повторить это поведение в python 2.5, 2.6 или 3.0 на mac os x-U+2028 всегда рассматривается как неэндлайн. Не могли бы вы подробнее рассказать о том, где вы видите эту ошибку?
Тем не менее, вот подкласс класса" file", который может делать то, что вы хотите:
#/usr/bin/python # -*- coding: utf-8 -*- class MyFile (file): def __init__(self, *arg, **kwarg): file.__init__(self, *arg, **kwarg) self.EOF = False def next(self, catchEOF = False): if self.EOF: raise StopIteration("End of file") try: nextLine= file.next(self) except StopIteration: self.EOF = True if not catchEOF: raise return "" if nextLine.decode("utf8")[-1] == u'\u2028': return nextLine+self.next(catchEOF = True) else: return nextLine A = MyFile("someUnicode.txt") for line in A: print line.strip("\n").decode("utf8")
Я не мог воспроизвести это поведение, но вот наивное решение, которое просто сливает результаты readline, пока они не заканчиваются U+2028.
#!/usr/bin/env python from __future__ import with_statement def my_readlines(f): buf = u"" for line in f.readlines(): uline = line.decode('utf8') buf += uline if uline[-1] != u'\u2028': yield buf buf = u"" if buf: yield buf with open("in.txt", "rb") as fin: for l in my_readlines(fin): print l
Спасибо всем за ответ. Я думаю, что знаю, почему вы не смогли бы повторить это.Я просто понял, что это происходит, если я декодирую файл при открытии, как в:
f = codecs.open(filename, encoding='utf-8') for line in f: print line
Строки не разделяются на u2028, если я сначала открою файл, а затем расшифрую отдельные строки:
f = open(filename) for line in f: print line.decode("utf8")
(я использую Python 2.6 в Windows. Файл был первоначально UTF16LE, а затем он был преобразован в UTF8).
Это очень интересно, я думаю, что не буду использовать кодеки.открыть много отныне: -).
Если вы используете Python 3.0 (обратите внимание, что я этого не делаю, поэтому я не могу тестировать), в соответствии с документацией Вы можете передать необязательный параметр
newline
вopen
, чтобы указать, какой разделитель строк использовать. Однако в документации вообще не упоминается U+2028 (упоминается только\r
,\n
, и\r\n
в качестве разделителей строк), так что это на самом деле удивительно для меня, что это вообще происходит (хотя я могу подтвердить это даже с Python 2.6).
Модуль кодеков делает все правильно. U+2028 называется " разделителем строк "с комментарием"может использоваться для однозначного представления этой семантики". Поэтому рассматривать его как разделитель линий разумно.
Предположительно создатель не поместил бы туда символы U+2028 без веской причины ... есть ли в файле также u "\n"? Почему вы хотите, чтобы линии не были разделены на U+2028?