【问题标题】:Python : Split string every three wordsPython:每三个单词拆分字符串
【发布时间】:2018-03-10 00:49:51
【问题描述】:

我已经搜索了一段时间,但我似乎无法找到这个小问题的答案。

我有这段代码应该在每三个单词之后拆分字符串:

import re

def splitTextToTriplet(Text):
    x = re.split('^((?:\S+\s+){2}\S+).*',Text)
    return x


print(splitTextToTriplet("Do you know how to sing"))

目前的输出是这样的:

['', 'Do you know', '']

但我实际上期待这个输出:

['Do you know', 'how to sing'] 

如果我打印(splitTextToTriplet("Do you know how to")),它也应该输出:

['Do you know', 'how to'] 

如何更改正则表达式以产生预期的输出?

【问题讨论】:

  • 解决方案必须是正则表达式吗?除了在第三个单词之后将字符串一分为二之外,是否需要任何其他逻辑?
  • 我同意@thesilkworm。可能有比使用正则表达式更简单的方法来做到这一点。正则表达式是必需的吗?
  • 并非如此。但是,如果您对如何解决此问题有其他建议,我也可以。 XD
  • 使用re.findall

标签: python regex python-3.x


【解决方案1】:

我相信re.split 可能不是解决此问题的最佳方法,因为look-behind 不能采用可变长度模式。

相反,您可以使用str.split,然后将单词连接在一起。

def splitTextToTriplet(string):
    words = string.split()
    grouped_words = [' '.join(words[i: i + 3]) for i in range(0, len(words), 3)]
    return grouped_words

splitTextToTriplet("Do you know how to sing")
# ['Do you know', 'how to sing']

splitTextToTriplet("Do you know how to")
# ['Do you know', 'how to'] 

虽然建议使用此解决方案,但如果您的某些空格是换行符,则该信息将在此过程中丢失。

【讨论】:

    【解决方案2】:

    我使用re.findall 作为您期望的输出。为了获得更通用的拆分功能,我将splitTextonWords 上的splitTextToTriplet 替换为numberOfWords 作为参数:

    import re
    
    def splitTextonWords(Text, numberOfWords=1):
        if (numberOfWords > 1):
            text = Text.lstrip()
            pattern = '(?:\S+\s*){1,'+str(numberOfWords-1)+'}\S+(?!=\s*)'
            x =re.findall(pattern,text)
        elif (numberOfWords == 1):
            x = Text.split()
        else: 
            x = None
        return x
    
    print(splitTextonWords("Do you know how to sing", 3))
    print(splitTextonWords("Do you know how to", 3))
    print(splitTextonWords("Do you know how to sing how to dance how to", 3))
    print(splitTextonWords("A sentence this code will fail at", 3))
    print(splitTextonWords("A sentence this             code will fail at ", 3))
    print(splitTextonWords("   A sentence this code will fail at s", 3))
    print(splitTextonWords("   A sentence this code will fail at s", 4))
    print(splitTextonWords("   A sentence this code will fail at s", 2))
    print(splitTextonWords("   A sentence this code will fail at s", 1))
    print(splitTextonWords("   A sentence this code will fail at s", 0))
    

    输出:

    ['你知道吗','如何唱歌']
    ['你知道','如何']
    ['你知道吗','如何唱歌','如何跳舞','如何']
    ['一句this', 'code会失败', 'at']
    ['一句this', 'code会失败', 'at']
    ['一句this', '代码会失败', 'at s']
    ['一句this code', 'will fail at s']
    ['一个句子', '这段代码', '会失败', 'at s']
    ['A', 'sentence', 'this', 'code', 'will', 'fail', 'at', 's']

    【讨论】:

    • 我解决了这个问题
    • 我想接受这两个答案,但我只能按一次。我想我要编辑标题,以便所有人都能找到它。
    【解决方案3】:

    使用grouperitertools recipe

    import itertools
    
    
    def grouper(iterable, n, fillvalue=None):
        "Collect data into fixed-length chunks or blocks"
        # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx"
        args = [iter(iterable)] * n
        return itertools.zip_longest(*args, fillvalue=fillvalue)
    

    另请参阅为您实现此配方的 more_itertools 第三方库。

    代码

    def split_text_to_triplet(s):
        """Return strings of three words."""
        return [" ".join(c) for c in grouper(3, s.split())]
    
    
    split_text_to_triplet("Do you know how to sing")
    # ['Do you know', 'how to sing']
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-01
      • 2023-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-08
      相关资源
      最近更新 更多