【问题标题】:Splitting on regex without removing delimiters在不删除分隔符的情况下拆分正则表达式
【发布时间】:2017-10-29 21:16:21
【问题描述】:

所以,我想把这段文字分成几个句子。

s = "You! Are you Tom? I am Danny."

所以我明白了:

["You!", "Are you Tom?", "I am Danny."]

那是我想用正则表达式 '[.!\?]' 分割文本而不删除分隔符。在python中实现这一点的最pythonic方法是什么?

我知道这些问题:

JS string.split() without removing the delimiters

Python split() without removing the delimiter

但我的问题有各种分隔符 (.?!),这使问题变得复杂。

【问题讨论】:

    标签: python regex split


    【解决方案1】:

    您可以将re.findall 与正则表达式.*?[.!\?] 一起使用;惰性量词 *? 确保每个模式都匹配到您要匹配的特定分隔符:

    import re
    
    s = """You! Are you Tom? I am Danny."""
    re.findall('.*?[.!\?]', s)
    # ['You!', ' Are you Tom?', ' I am Danny.']
    

    【讨论】:

      【解决方案2】:

      如果 Python 支持按零长度匹配进行拆分,您可以通过匹配前面有一个分隔符的空字符串来实现:

      (?<=[.!?])
      

      演示:https://regex101.com/r/ZLDXr1/1

      很遗憾,Python does not support split by zero-length matches。然而,该解决方案在其他支持lookbehinds 的语言中可能仍然有用。

      但是,根据您的输入/输出数据样本,您宁愿需要用一个分隔符前面的空格来分割。所以正则表达式是:

      (?<=[.!?])\s+
      

      演示:https://regex101.com/r/ZLDXr1/2

      Python 演示:https://ideone.com/z6nZi5

      如果空格是可选的,我相信@Psidom 建议的re.findall 解决方案是最好的。

      【讨论】:

      • 我认为我没有足够清楚地说明我的问题。如果[.\?!] 后面现在有空格怎么办?
      • Python 从 3.7 开始支持零长度匹配。
      【解决方案3】:

      严格来说,您不想在 '!?.' 上进行拆分,而是在这些字符后面的空格上进行拆分。以下将起作用:

      >>> import re
      >>> re.split(r'(?<=[\.\!\?])\s*', s)
      ['You!', 'Are you Tom?', 'I am Danny.']
      

      这会在空格上拆分,但前提是它前面有 .、! 或 ?字符。

      【讨论】:

        【解决方案4】:

        如果您更喜欢使用拆分方法而不是匹配,则一种解决方案与组拆分

        splitted = filter(None, re.split( r'(.*?[\.!\?])', s))
        

        过滤器删除空字符串(如果有)。

        即使句子之间没有空格,或者如果您需要捕获以不同标点符号结尾的尾随句子,例如 unicode 省略号(或根本没有),这也可以工作

        甚至可以保持原样(通过转义更正和添加括号)。

        splitted = filter(None, re.split( r'([\.!\?])', s))
        

        然后合并均匀和不均匀的元素,去掉多余的空格

        Python split() without removing the delimiter

        【讨论】:

          【解决方案5】:

          最简单的方法是使用nltk

          import nltk   
          nltk.sent_tokenize(s)
          

          它将返回所有句子的列表,而不会丢失分隔符。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-05-10
            • 1970-01-01
            • 2013-06-22
            • 1970-01-01
            • 2019-01-21
            • 2014-10-15
            • 2016-02-07
            • 2012-06-29
            相关资源
            最近更新 更多