【问题标题】:Reduce multiple blank lines to single (Pythonically)将多个空行减少为单个(Pythonically)
【发布时间】:2015-05-08 05:10:13
【问题描述】:

如何将文本文件中的多个空行减少为每次出现的一行?

我已将整个文件读入一个字符串,因为我想跨行结尾进行一些替换。

with open(sourceFileName, 'rt') as sourceFile:
    sourceFileContents = sourceFile.read()

这个好像不行

while '\n\n\n' in sourceFileContents:
    sourceFileContents = sourceFileContents.replace('\n\n\n', '\n\n')

这也不是

sourceFileContents = re.sub('\n\n\n+', '\n\n', sourceFileContents)

将它们全部剥离很容易,但我想在每次遇到它们时将多个空行减少到一个。

我觉得我已经很接近了,但就是无法让它发挥作用。

【问题讨论】:

    标签: python regex python-3.x


    【解决方案1】:

    这是一个范围,但也许有些行不是完全空白的(即它们只有空白字符,看起来像是空白)。您可以尝试删除换行符之间所有可能的空格。

    re.sub(r'(\n\s*)+\n+', '\n\n', sourceFileContents)
    

    编辑:意识到第二个“+”是多余的,因为 \s* 会在第一个和最后一个之间捕获换行符。我们只是想确保最后一个字符绝对是换行符,这样我们就不会从包含其他内容的行中删除前导空格。

    re.sub(r'(\n\s*)+\n', '\n\n', sourceFileContents)
    

    编辑 2

    re.sub(r'\n\s*\n', '\n\n', sourceFileContents)
    

    应该是一个更简单的解决方案。我们真的只是想在我们的两个锚换行符之间捕获任何可能的空格(包括中间换行符),这将形成一个空行并将其折叠成两个换行符。

    【讨论】:

    • 是只去掉空格,还是减少多个空行?
    • 应该两者都做,至少从我的简单测试来看。它不应该从包含其他内容的行的开头删除空格。
    【解决方案2】:

    您的代码对我有用。也许有回车\r的机会。

    re.sub(r'[\r\n][\r\n]{2,}', '\n\n', sourceFileContents)
    

    【讨论】:

      【解决方案3】:

      你可以只使用 str 方法 split 和 join:

      text = "some text\n\n\n\nanother line\n\n"
      print("\n".join(item for item in text.split('\n') if item))
      

      【讨论】:

        【解决方案4】:

        如果您将 read 语句替换为以下内容,则不必担心空格或回车:

        with open(sourceFileName, 'rt') as sourceFile:
            sourceFileContents = ''.join([l.rstrip() + '\n' for l in sourceFile])
        

        执行此操作后,您在 OP 中尝试的两种方法都有效。

        只需在一个简单的循环中写出来。

        with open(sourceFileName, 'rt') as sourceFile:
            lines = ['']
            for line in (l.rstrip() for l in sourceFile):
                if line != '' or lines[-1] != '\n':
                    lines.append(line + '\n')
            sourceFileContents = "".join(lines)
        

        【讨论】:

          【解决方案5】:

          如果行完全为空,您可以使用正则表达式positive lookahead 将它们替换为单行:

          sourceFileContents = re.sub(r'\n+(?=\n)', '\n', sourceFileContents)
          

          【讨论】:

            【解决方案6】:

            我猜另一个选项更长,但可能更漂亮?

            with open(sourceFileName, 'rt') as sourceFile:
                last_line = None
                lines = []
                for line in sourceFile:
                     # if you want to skip lines with only whitespace, you could add something like:
                        # line = line.lstrip(" \t")
                    if last_line != "\n":
                        lines.append(line)
                    last_line = line
             contents = "".join(lines)
            

            我试图找到一些聪明的生成器函数方法来写这个,但是这已经是漫长的一周,所以我做不到。

            代码未经测试,但我认为它应该可以工作?

            (编辑:一个好处是我不再需要正则表达式来解决“现在你有两个问题”问题:))

            (基于 Marc Chiesa 建议的挥之不去的空白的另一个编辑)

            【讨论】:

            • 你可以用 lines[-1] 代替最后一行。也只是做 line.rstrip() 会从行尾删除所有空格(这是一件好事)并返回一个空字符串。
            • 大声笑 - 现在你有两个问题 :-) 对于那些不认识引用的人,请参阅 programmers.stackexchange.com/questions/223634/…
            • @cdhagmann - 在这种情况下不起作用 - 我总是想查看文件的最后一行,而不是我添加到列表中的最后一行。
            【解决方案7】:

            对于像我这样不会做正则表达式的人,如果要处理的代码是python:

            import autopep8
            
            autopep8.fixcode('your_code')
            

            另一个快速解决方案,以防您的代码不是 Python:

            for x in range(100):
                content.replace("  ", " ")   # reduce the number of multiple whitespaces
            
            # then
            for x in range(20):
                content.replace("\n\n", "\n")   # reduce the number of multiple white lines
            

            请注意,如果您有超过 100 个连续的空格或 20 个连续的新行,则需要增加重复次数。

            【讨论】:

              【解决方案8】:

              使用re 模块的非常简单的方法

              import re
              
              text = 'Abc\n\n\ndef\nGhijk\n\nLmnop'
              text = re.sub('[\n]+', '\n', text) # Replacing one or more consecutive newlines with single \n
              

              结果:

              'Abc\ndef\nGhijk\nLmnop'

              【讨论】:

                【解决方案9】:

                如果从 unicode 解码,请注意在 cat -vet 中显示为 M-BM- 的不间断空格:

                sourceFileContents = sourceFile.read()
                sourceFileContents = re.sub(r'\n(\s*\n)+','\n\n',sourceFileContents.replace("\xc2\xa0"," "))
                

                【讨论】:

                  猜你喜欢
                  • 2015-06-30
                  • 2019-02-20
                  • 2018-08-03
                  • 1970-01-01
                  • 2021-01-01
                  • 2019-10-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多