【问题标题】:Removing odd \n, \t, \r and space combinations from a given string in Python从 Python 中的给定字符串中删除奇数 \n、\t、\r 和空格组合
【发布时间】:2013-07-22 11:01:55
【问题描述】:

我有一个长字符串,其中包含 \n、\r、\t 以及单词和其他字符之间的空格的各种组合。

  • 我想将所有多个空格缩减为一个空格。
  • 我想将所有 \n、\r、\t 组合减少为单个换行符。
  • 我也想将所有 \n、\r、\t 和空格组合减少为单个换行符。

我以各种方式尝试了''.join(str.split()),但均未成功。

  • 这里正确的 Pythonic 方式是什么?

  • Python 3.x 的解决方案会有所不同吗?

例如。字符串:

ex_str = u'Word   \n \t \r   \n\n\n word2    word3   \r\r\r\r\nword4\n    word5'

所需的输出 [new new-line = \n]:

new_str = u'Word\nword2 word3\nword4\nword5'

【问题讨论】:

  • 不要命名变量str;它掩盖了内置类型。
  • “我也想将所有 \n、\r、\t 和空格组合减少为一个换行符。” 连续计算两个空格作为“\n、\r、\t 和空格组合”?如果是,你如何决定何时使用这条规则,何时使用第一条规则?
  • @Kevin,在单词之间,我有任何东西,从单个 \n、单个 \t、单个 \r、单个空格到任何(或相同)的 1、2、3 或全部 4其中。如果任何组合有一个或多个新行,我希望它是一个新行。如果它只有空格(一个或多个),我希望它是一个空格。
  • @MartijnPieters,我替换了示例字符串名称。谢谢。
  • 你需要澄清你在换行规则中包含\tword1\t\tword2 应该是 word1 word2 还是 word1\nword2

标签: python string python-2.7 replace split


【解决方案1】:

使用str.splitlines() 的组合并使用str.split() 分割所有空格:

'\n'.join([' '.join(line.split()) for line in ex_str.splitlines() if line.strip()])

这会分别处理每一行,删除空行,然后将每行的所有空白折叠成单个空格。

如果输入是 Python 3 字符串,则相同的解决方案适用于两个 Python 版本。

演示:

>>> ex_str = u'Word   \n \t \r   \n\n\n word2    word3   \r\r\r\r\nword4\n    word5'
>>> '\n'.join([' '.join(line.split()) for line in ex_str.splitlines() if line.strip(' ')])
u'Word\nword2 word3\nword4\nword5'

要保留选项卡,您需要在 个空格上剥离和拆分并过滤掉空字符串:

'\n'.join([' '.join([s for s in line.split(' ') if s]) for line in ex_str.splitlines() if line.strip()])

演示:

>>> '\n'.join([' '.join([s for s in line.split(' ') if s]) for line in ex_str.splitlines() if line.strip(' ')])
u'Word\n\t\nword2 word3\nword4\nword5'

【讨论】:

  • 如果是\t\t ,这可能不能满足需求3。它应该由换行符替换。 @Martijn Pieters
  • @zhangyangyu:我不是 100% 相信是这样的。
  • 我认为简单的\ts 也应该转换为换行符。但是,示例字符串没有这种情况。
  • @Alfe:请参阅问题上的 cmets; OP 对这些感到困惑。
  • 我看到了cmets。对于制表符是否应转换为换行符的问题,我没有看到混淆,至少在澄清»word1\t\tword2 应该是 word1\nword2« 之后不会混淆。但无论如何,他后来问了一个忽略标签的新功能,所以你也许他重新考虑了;-)
【解决方案2】:

使用简单的正则表达式:

import re
new_str = re.sub(r'[^\S\n]+', ' ', re.sub(r'\s*[\n\t\r]\s*', '\n', ex_str))

【讨论】:

    【解决方案3】:

    使用正则表达式:

    >>> s
    u'Word   \n \t \r   \n\n\n word2    word3   \r\r\r\r\nword4\t    word5'
    >>> re.sub(r'[\n\r\t ]{2,}| {2,}', lambda x: '\n' if x.group().strip(' ') else ' ', s)
    u'Word\nword2 word3\nword4\nword5'
    >>> 
    

    【讨论】:

      【解决方案4】:

      另一种使用正则表达式的解决方案,它用空格u'word1\t\tword2' 替换制表符,或者你真的想在这里添加换行符吗?

      import re
      new_str = re.sub(r"[\n\ ]{2,}", "\n", re.sub(r"[\t\r\ ]+", " ", ex_str))
      

      【讨论】:

        【解决方案5】:
        '\n'.join(str.split())
        

        输出:

        u'Word\nword2\nword3\nword4\nword5'
        

        【讨论】:

        • 仔细看看预期的输出 ;)
        • 您将word2word3 之间的空格替换为换行符。
        猜你喜欢
        • 2019-10-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-04
        • 2019-02-04
        • 1970-01-01
        • 2019-05-21
        相关资源
        最近更新 更多