【问题标题】:python regular expression to split paragraphspython正则表达式分割段落
【发布时间】:2010-09-12 02:28:47
【问题描述】:

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

段落由 2 个换行符 (\n) 定义。但是可以有任意数量的空格/制表符以及换行符,它仍然应该被视为一个段落。

我正在使用 python,所以解决方案可以使用 python 的 regular expression syntax 扩展。 (可以使用(?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 个 \ns 的段落分隔符。

【问题讨论】:

    标签: python regex parsing text split


    【解决方案1】:

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

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

    【讨论】:

    • 这会使示例 2 失败,因为 \s 包含 \n。
    【解决方案2】:

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

    您也许可以简单地使用Docutils parser 而不是自己滚动。

    【讨论】:

      【解决方案3】:

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

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

      您也可以尝试为角色类创建一个子规则并插入 3 次。

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

        • 简洁的解决方案。 str_isspace 是什么?
        • 一个错字:-) 您应该从对象字符串中读取方法 isspace() 的 str.isspace。它将被调用以确定某物是否为空间,并据此对对象进行分组。我修好了。
        【解决方案5】:

        仅供参考:我刚刚在另一个线程中为此类问题编写了 2 个解决方案。首先使用此处要求的正则表达式,其次使用状态机方法,一次通过输入流:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-04-02
          • 2014-08-05
          • 1970-01-01
          • 1970-01-01
          • 2018-10-13
          • 2011-04-06
          相关资源
          最近更新 更多