регулярное выражение Python для разделения абзацев - PullRequest
5 голосов
/ 22 сентября 2008

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

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

Я использую 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)

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

EDIT

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

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

Ответы [ 4 ]

4 голосов
/ 22 сентября 2008

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

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

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

2 голосов
/ 22 сентября 2008

Вы пытаетесь вывести структуру документа в виде простого теста? Вы делаете то, что documenttils делает?

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

1 голос
/ 24 сентября 2008

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

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"; -)

0 голосов
/ 22 сентября 2008

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

\s*?\n\s*?\n\s*?
...