【问题标题】:Replace multiple newlines with single newlines during reading file在读取文件期间用单个换行符替换多个换行符
【发布时间】:2017-03-06 15:34:07
【问题描述】:

我有下一个代码,它从多个文件中读取,解析获得的行并打印结果:

import os
import re

files=[]
pars=[]

for i in os.listdir('path_to_dir_with_files'):
    files.append(i)

for f in files:
    with open('path_to_dir_with_files'+str(f), 'r') as a:
       pars.append(re.sub('someword=|\,.*|\#.*','',a.read()))

for k in pars:
   print k

但我在输出中有多个新行有问题:

test1


test2

我想获得下一个结果,而不是输出中的空行:

 test1
 test2

等等。

我尝试使用正则表达式:

pars.append(re.sub('someword=|\,.*|\#.*|^\n$','',a.read()))

但它不起作用。我也尝试使用 strip() 和 rstrip() 包括替换。它也不起作用。

【问题讨论】:

    标签: python regex file


    【解决方案1】:

    您可以使用第二个正则表达式将多个新行替换为一个新行,并使用 strip 删除最后一个新行。

    import os
    import re
    
    files=[]
    pars=[]
    
    for i in os.listdir('path_to_dir_with_files'):
        files.append(i)
    
    for f in files:
        with open('path_to_dir_with_files/'+str(f), 'r') as a:
            word = re.sub(r'someword=|\,.*|\#.*','', a.read())
            word = re.sub(r'\n+', '\n', word).strip()
            pars.append(word)
    
    for k in pars:
       print k
    

    【讨论】:

    • 你可以按行而不是按文件吗?就像 f 中的 for line:你能解释一下 re.sub 的作用吗?逗号和哈希被转义,我不明白 someword=。示例中没有 =..
    • 当然你可以逐行执行,但f 在这种情况下是文件名而不是内容。 re.sub 将与第一个参数匹配的内容替换为您在第二个参数中输入的内容。查看文档并尝试一下。
    【解决方案2】:

    无需过多更改代码,一种简单的方法就是在打印之前检查该行是否为空,例如:

    import os
    import re
    
    files=[]
    pars=[]
    
    for i in os.listdir('path_to_dir_with_files'):
        files.append(i)
    
    for f in files:
        with open('path_to_dir_with_files'+str(f), 'r') as a:
            pars.append(re.sub('someword=|\,.*|\#.*','',a.read()))
    
    for k in pars:
        if not k.strip() == "":
            print k
    

    *** 编辑 由于 pars 中的每个元素实际上是文件的全部内容(不仅仅是一行),因此您需要通过替换任何双端行,最简单的方法是 re

    import os
    import re
    
    files=[]
    pars=[]
    
    for i in os.listdir('path_to_dir_with_files'):
        files.append(i)
    
    for f in files:
        with open('path_to_dir_with_files'+str(f), 'r') as a:
            pars.append(re.sub('someword=|\,.*|\#.*','',a.read()))
    
    for k in pars:
        k = re.sub(r"\n+", "\n", k)
        if not k.strip() == "":
            print k
    

    请注意,这不会处理文件以换行符结尾而下一个文件以换行符开头的情况 - 如果您担心这种情况,您需要添加额外的逻辑来处理它或更改你读取数据的方式

    【讨论】:

    • 或者只是if k.strip()
    • 这也应该在添加到 pars 时完成,而不是在迭代 pars 时完成。
    • 不幸的是,它没有给出合适的结果。如果不是 k.strip() == "" 我仍然会获得多个空行。如果只显示列表而不遍历它,我会得到:test1[]\n\n\n test2\n test5\ntest7[]\ntest[*]\n etc...
    • 哦,我明白了,因为您只是将整行读入 pars 中的每个项目,所以它不是逐行打印。我编辑了我的答案,它只是使用正则表达式来通过并用单个 \n 删除任何重复的 \n
    【解决方案3】:

    只是一个简单的,但可能效率不高。

    entire_file = "whatever\nmay\n\n\n\nhappen"
    
    while '\n\n' in entire_file:
        entire_file = entire_file.replace("\n\n", "\n")
    
    print(entire_file)
    

    【讨论】:

    • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
    【解决方案4】:

    使用前瞻正则表达式查找所有双返回字符r'\n(?=\n) 并将其替换为空。这将一次性找到并替换所有这些情况

    import re
    
    files=[]
    pars=[]
    
    for i in os.listdir('path_to_dir_with_files'):
        files.append(i)
    
    for f in files:
        with open('path_to_dir_with_files'+str(f), 'r') as a:
           pars.append(re.sub(r'\n(?=\n)','',a.read()))
    
    for k in pars:
       print k
    

    注意:如果最后一个字符是文件 [0] 的 \n 并且文件 [1] 的第一个字符也是 '\n',这对你没有帮助,但是......你可以使用 strip 和你的print 将处理文件之间的单个空间

    import os
    import re
    
    files=[]
    pars=[]
    
    for i in os.listdir('path_to_dir_with_files'):
        files.append(i)
    
    for f in files:
        with open('path_to_dir_with_files'+str(f), 'r') as a:
           pars.append(re.sub(r'\n(?=\n)','',a.read().strip()))
    
    for k in pars:
       print k
    

    【讨论】:

      【解决方案5】:

      只想指出:正则表达式不是处理该问题的最佳方式。将 Python str 中的两个空行替换为一个非常简单,不需要 re:

      entire_file = "whatever\nmay\n\nhappen"
      entire_file = entire_file.replace("\n\n", "\n")
      

      瞧!比 re 快得多,而且(在我看来)更容易阅读。

      【讨论】:

      • 如果文件包含超过 2 个连续的“\n”,例如“whatever\nmay\n\n\nhappen”,这将不起作用
      • 确实如此,但仍然可以使用循环:while "\n\n" in text: text = text.replace("\n\n", "\n")
      • 这种“省略”形式很脆弱,需要根据所需运行的长度进行调整。例如。在“段落”之间需要两个换行符需要 三个 .replace("\n\n\n", "\n\n") 调用。迭代重建意味着每次迭代复制整个字符串。正则表达式可以更轻松地结合重复字符的实际测量运行,并明确控制运行长度:\n{min,max},并且基本上在 O(1) 时间内执行这样的操作,而不会产生过多的内存重复.
      猜你喜欢
      • 2011-05-02
      • 1970-01-01
      • 1970-01-01
      • 2021-03-24
      • 1970-01-01
      • 2021-02-12
      • 2020-04-17
      • 2017-05-05
      相关资源
      最近更新 更多