2009-07-29 3 views
6

У меня есть строка, которую я пытаюсь разбить на куски на пустых строках.Соответствующие пустые строки с регулярными выражениями

Учитывая строку s, я думал, что я мог бы сделать это:

re.split('(?m)^\s*$', s) 

Это работает в некоторых случаях:

>>> s = 'foo\nbar\n \nbaz' 
>>> re.split('(?m)^\s*$', s) 
['foo\nbar\n', '\nbaz'] 

Но это не работает, если линия полностью разряжен:

>>> s = 'foo\nbar\n\nbaz' 
>>> re.split('(?m)^\s*$', s) 
['foo\nbar\n\nbaz'] 

Что я делаю неправильно?

[python 2.5; нет разницы, если я компилирую '^\s*$' с re.MULTILINE и использую скомпилированное выражение вместо этого]

+0

ли \ s там, потому что эти линии могут или не могут содержать пробельных символов? – anschauung

+0

Можете ли вы показать некоторые входные данные и примеры вывода? – ghostdog74

+1

Выглядит так, как будто это работает. Из http://docs.python.org/library/re.html: «split никогда не будет разбивать строку на пустую совпадение шаблона». Для рабочей версии см. Ответ Гленна Мейнарда ('\ n \ s * \ n'), но обратите внимание на его предупреждение об обработке нескольких пустых/пробельных строк. Вместо этого вы могли бы попытаться создать что-то вокруг re.finditer. –

ответ

17

Попробуйте вместо этого:

re.split('\n\s*\n', s) 

Проблема заключается в том, что «$ * ^» на самом деле соответствует только «пробелы (если таковые имеются), которые одни на линии» - а не сами символы новой строки. Это оставляет разделитель пустым, когда на линии нет ничего, что не имеет смысла.

Эта версия также избавляет от разделительных линий, которые, вероятно, вы хотите. В противном случае вы будете иметь новые строки, прикрепленные к началу и концу каждой разделенной части.

Обработка несколько последовательных пустых строк как определение пустого блока ("а \ п \ п \ ЦНК" -> [ "ABC", "", "DEF"]) является хитрым ...

+0

Однако он оставляет четные пустые строки в начале их кусков, что может быть нежелательно. – eswald

+0

Попробуйте альтернативу (добавлено). –

+0

Забавно, как ваш ум может застрять в колею .. Мне понадобилось многострочное изображение для некоторых других совпадений, и поэтому было очевидно использовать его здесь. Так много для «очевидного». Я сохраню ответ Зака ​​как принятый, потому что он процитировал мою точную ситуацию из документов, но ваш ответ тоже очень полезен! –

-2

Что вы делаете неправильно, используйте регулярные выражения. Что не так («Some \ ntext.»). Split ('\ n')?

+2

Он хочет совместить пустые строки, которые могут иметь пробелы.Разделение на «\ n» будет разделять каждую линию отдельно. Splittong на "\ n \ n" (что, вероятно, вы подразумевали) не будет работать на пустые строки с пробелами на них. –

+0

, потому что это не разделяет вход, на который он просил. Он хочет разделить группы текста несколькими символами новой строки. IE две строки, содержащие текст, разделенные одной новой строкой, не разделяются, но если они разделены двумя (или предположительно больше) символами новой строки, с пробелами только на пустых строках, они должны быть раздельными. – SingleNegationElimination

+0

Так что не говорите «пусто», если вы не имеете в виду «пустое». –

0

Это что ты хочешь?

>>> s = 'foo\nbar\n\nbaz' 
>>> re.split('\n\s*\n',s) 
['foo\nbar', 'baz'] 

>>> s = 'foo\nbar\n \nbaz' 
>>> re.split('\n\s*\n',s) 
['foo\nbar', 'baz'] 

>>> s = 'foo\nbar\n\t\nbaz' 
>>> re.split('\n\s*\n',s) 
['foo\nbar', 'baz'] 
3

Библиотека re может разбиваться на одну или несколько пустых строк! Пустая строка - это строка, состоящая из нуля или более пробелов, начинается с начала строки и заканчивается в конце строки. Специальный символ '$' соответствует концу строки или непосредственно перед новой строкой в ​​конце строки, а в режиме MULTILINE также соответствует перед новой строкой (выдержка из docs). Вот почему нам нужно добавить специальный символ '\ s *' для разрыва строки. Все возможно :-)

>>> import re 
>>> text = "foo\n \n \n \nbar\n" 
>>> re.split("(?m)^\s*$\s*", text) 
['foo\n', 'bar\n'] 

Такое же регулярное выражение работает с разрывами строк в стиле окна.

>>> import re 
>>> text = "foo\r\n  \r\n  \r\n \r\nbar\r\n" 
>>> re.split("(?m)^\s*$\s*", text) 
['foo\r\n', 'bar\r\n'] 
+0

Чтобы удалить прерывания строки, вы должны добавить '\ s *' перед '^' следующим образом: 're.split (" (? M) \ s *^\ s * $ \ s * ", text)' – renskiy

0

Попробуйте это:

blank='' 
with open('fu.txt') as txt: 
    txt=txt.read().split('\n') 
    for line in txt: 
     if line is blank: print('blank') 
     else: print(line) 
Смежные вопросы