Регулярное выражение Python для разделения абзацев

StackOverflow https://stackoverflow.com/questions/116494

Вопрос

Как написать регулярное выражение для использования в Python для разделения абзацев?

Абзац определяется двумя разрывами строк ( ).Но вместе с переносами строк может быть любое количество пробелов/табуляций, и это все равно следует рассматривать как абзац.

Я использую Python, поэтому решение может использовать Python синтаксис регулярных выражений который продлен.(можно использовать (?P...) вещи)

Примеры:

the_str = 'paragraph1\n\nparagraph2'
# splitting should yield ['paragraph1', 'paragraph2']

the_str = 'p1\n\t\np2\t\n\tstill p2\t   \n     \n\tp3'
# should yield ['p1', 'p2\t\n\tstill p2', 'p3']

the_str = 'p1\n\n\n\tp2'
# should yield ['p1', '\n\tp2']

Лучшее, что я мог предложить, это: r'[ \t\r\f\v]*\n[ \t\r\f\v]*\n[ \t\r\f\v]*', т.е.

import re
paragraphs = re.split(r'[ \t\r\f\v]*\n[ \t\r\f\v]*\n[ \t\r\f\v]*', the_str)

но это некрасиво.Что-нибудь лучше?

РЕДАКТИРОВАТЬ:

Предложения отклонены:

r'\s*?\n\s*?\n\s*?' -> Это приведет к провалу примеров 2 и 3, поскольку \s включает \n, поэтому можно было бы разрешить разрывы абзацев более чем двумя \nс.

Это было полезно?

Решение

К сожалению, нет хорошего способа написать «пробел, но не новую строку».

Я думаю, лучшее, что вы можете сделать, это добавить немного места с помощью x модификатор и попытайтесь немного сгладить уродство, но это сомнительно: (?x) (?: [ \t\r\f\v]*? \n ){2} [ \t\r\f\v]*?

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

Другие советы

Вы пытаетесь определить структуру документа с помощью простого теста?Ты делаешь что? документы делает?

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

Не регулярное выражение, но очень элегантное:

from itertools import groupby

def paragraph(lines) :
    for group_separator, line_iteration in groupby(lines.splitlines(True), key = str.isspace) :
        if not group_separator :
            yield ''.join(line_iteration)

for p in paragraph('p1\n\t\np2\t\n\tstill p2\t   \n     \n\tp'): 
    print repr(p)

'p1\n'
'p2\t\n\tstill p2\t   \n'
'\tp3'

Разумеется, вы можете обрезать вывод по мере необходимости.

Вдохновлен знаменитой «Поваренной книгой Python» ;-)

Почти то же самое, но с использованием нежадных кванторов и преимуществами последовательности пробелов.

\s*?\n\s*?\n\s*?
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top