Python 正则表达式分割段落

6 投票
4 回答
11722 浏览
提问于 2025-04-11 09:18

如何在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)

但这个看起来不太好。有更好的方法吗?

被拒绝的建议:

r'\s*?\n\s*?\n\s*?' -> 这个会让例子2和3失败,因为\s包含了\n,所以它会允许段落之间有超过两个\n的换行。

4 个回答

2

你可能在尝试理解一个文档的结构,像 docutils 那样去做。

其实你可以直接使用 Docutils 的解析器,而不需要自己从头开始写一个。

3

这不是正则表达式,但它真的很优雅:

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 Cookbook》(《Python 食谱》);-)

6

很遗憾,没有简单的方法来表示“空格但不是换行”。

我觉得你能做的最好就是用x修饰符来添加一些空格,并尽量让代码看起来不那么丑,但这也有点争议:(?x) (?: [ \t\r\f\v]*? \n ){2} [ \t\r\f\v]*?

你也可以尝试创建一个子规则,专门用来处理字符类,然后把它插入三次。

撰写回答