5

如何编写一个正则表达式在 python 中使用来分割段落?

一个段落由 2 个换行符 (\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,因此它将允许超过 2\n秒的段落中断。

4

5 回答 5

5

不幸的是,没有写“空格但不是换行符”的好方法。

我认为你能做的最好的事情就是用x修饰符添加一些空间,并尝试将丑陋因素排除在外,但这是值得怀疑的:(?x) (?: [ \t\r\f\v]*? \n ){2} [ \t\r\f\v]*?

您也可以尝试仅为字符类创建一个子规则并对其进行 3 次插值。

于 2008-09-22T18:28:47.923 回答
2

您是否试图在普通测试中推断出文档的结构?你在做docutils做的事情吗?

您也许可以简单地使用Docutils 解析器,而不是自己动手。

于 2008-09-22T18:28:28.067 回答
2

不是正则表达式,但非常优雅:

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

于 2008-09-23T20:54:44.837 回答
0

几乎相同,但使用非贪婪量词并利用空白序列。

\s*?\n\s*?\n\s*?
于 2008-09-22T18:18:09.633 回答
0

FYI: I just wrote 2 solutions for this type of problem in another thread. First using regular expressions as requested here, and second using a state machine approach which streams through the input one line at a time:

https://stackoverflow.com/a/64863601/5201675

于 2020-11-16T19:33:42.847 回答