Какой самый питонный способ нормализации линейных концов в строке? - PullRequest
7 голосов
/ 17 ноября 2009

Учитывая текстовую строку неизвестного источника, как лучше всего переписать ее, чтобы иметь известное линейное соглашение?

Я обычно делаю:

lines = text.splitlines()
text = '\n'.join(lines)

... но это не относится к «смешанным» текстовым файлам совершенно запутанных соглашений (Да, они все еще существуют!).

Редактировать

Само собой разумеется, что я делаю:

'\n'.join(text.splitlines())

... я не об этом спрашиваю.

Впоследствии общее количество строк должно быть одинаковым, поэтому не нужно удалять пустые строки.

Testcases

Расщепление

'a\nb\n\nc\nd'
'a\r\nb\r\n\r\nc\r\nd'
'a\rb\r\rc\rd'
'a\rb\n\rc\rd'
'a\rb\r\nc\nd'
'a\nb\r\nc\rd'

.. должно привести к 5 строкам. В смешанном контексте splitline предполагает, что '\ r \ n' - это одна логическая новая строка, приводящая к 4 строкам для последних двух тестовых случаев.

Хм, смешанный контекст, содержащий '\ r \ n', может быть обнаружен путем сравнения результатов splitlines () и split ('\ n') и / или split ('\ r') ...

Ответы [ 3 ]

13 голосов
/ 17 ноября 2009
mixed.replace('\r\n', '\n').replace('\r', '\n')

должен обрабатывать все возможные варианты.

7 голосов
/ 17 ноября 2009

... но это не относится к "смешанным" текстовым файлам совершенно запутанных соглашений (Да, они все еще существуют!)

На самом деле все должно работать нормально:

>>> s = 'hello world\nline 1\r\nline 2'

>>> s.splitlines()
['hello world', 'line 1', 'line 2']

>>> '\n'.join(s.splitlines())
'hello world\nline 1\nline 2'

Какую версию Python вы используете?

РЕДАКТИРОВАТЬ: Я все еще не понимаю, как splitlines() не работает для вас:

>>> s = '''\
... First line, with LF\n\
... Second line, with CR\r\
... Third line, with CRLF\r\n\
... Two blank lines with LFs\n\
... \n\
... \n\
... Two blank lines with CRs\r\
... \r\
... \r\
... Two blank lines with CRLFs\r\n\
... \r\n\
... \r\n\
... Three blank lines with a jumble of things:\r\n\
... \r\
... \r\n\
... \n\
... End without a newline.'''

>>> s.splitlines()
['First line, with LF', 'Second line, with CR', 'Third line, with CRLF', 'Two blank lines with LFs', '', '', 'Two blank lines with CRs', '', '', 'Two blank lines with CRLFs', '', '', 'Three blank lines with a jumble of things:', '', '', '', 'End without a newline.']

>>> print '\n'.join(s.splitlines())
First line, with LF
Second line, with CR
Third line, with CRLF
Two blank lines with LFs


Two blank lines with CRs


Two blank lines with CRLFs


Three blank lines with a jumble of things:



End without a newline.

Насколько я знаю, splitlines() не делит список дважды или что-либо еще.

Можете ли вы вставить образец того типа ввода, который доставляет вам проблемы?

0 голосов
/ 17 ноября 2009

Есть ли еще больше конвекций, чем \r\n\ и \n? Достаточно просто заменить \r\n, если вам не нужны строки.

only_newlines = mixed.replace('\r\n','\n')
...