【问题标题】:Delete specific strings and specific empty line in python删除python中的特定字符串和特定空行
【发布时间】:2019-10-09 17:16:43
【问题描述】:

我正在删除文本文件中的特定字符串和空行,这是我之前的问题的后续内容...我参考了我们的 SO 专家的一些示例和解决方案...通过删除字符串效果很好,但是不是空行。为了便于理解,我在这里强调了这个问题。

文本文件的某些部分包含 stringA、stringB 和 stringC 行以及它下面的空行,只删除它下面的单行。

line0
line1      stringAxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
line2                stringBxxxxxxxxxxxxxxxxxxxxxxx
line3        stringCxxxxxxxxxxxxxxxxxxx 
line4
line5
line6  textxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
line7  textxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
line8  
line9  textxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
line10 textxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
line11               stringBxxxxxxxxxxxxxxxxxxxxxxx
line12       stringCxxxxxxxxxxxxxxxxxxx  
line13
line14
line15  textxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
line16  textxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
line17 
line18  textxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
line19  textxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
line20
line21  textxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
line22  textxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
line23 
line24  textxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
line25  textxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
line26               stringBxxxxxxxxxxxxxxxxxxxxxxx
line27       stringCxxxxxxxxxxxxxxxxxxx  
line28
line29
line30  textxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
line31  textxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
line32  

在这种情况下,删除任何包含 stringA、stringB、stringC 和其后一行的行。例如上面,删除第 1,2,3,4 行删除第 11,12,13 行删除第 26,27,28 行

我尝试过使用 strip() 但它删除了所有空行。这是我使用的脚本,它确实删除了所有包含 stringA、stringB 和 stringC 的行。

filename = 'raw.txt'
with open(filename, 'r') as fin:
    lines = fin.readlines()
with open('clean.txt', 'w') as fout:
   for line in lines:
        if not re.match(r"\s+(stringA|stringB|stringC)", line):
            fout.write(line)

预期输出

line0
line5
line6  textxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
line7  textxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
line8  
line9  textxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
line10 textxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
line14
line15  textxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
line16  textxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
line17 
line18  textxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
line19  textxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
line20
line21  textxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
line22  textxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
line23 
line24  textxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
line25  textxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
line29
line30  textxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
line31  textxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
line32  

感谢您的帮助和善意的帮助。谢谢。

【问题讨论】:

    标签: python string text


    【解决方案1】:

    我很确定这不是最佳答案,但“类似标志”的方法有效:

    import re
    filename = 'raw.txt'
    with open(filename, 'r') as fin:
        lines = fin.readlines()
    
    flag = 0
    
    with open('clean.txt', 'w') as fout:
        for line in lines:
            if not re.match(r'.*(stringA|stringB|stringC)', line):
                if not flag:
                    fout.write(line)
                flag = 0
            else:
                flag = 1
    

    希望对你有帮助

    【讨论】:

    • 您好先生...您的方法也有效...我以前没有使用过标志...感谢您能解释一下...谢谢
    • @chenoi,您好,标志是一个形象化的图像,您使用一种类型,大多数情况下是一个字符或一个整数,以表示发生了一些事情。在那种情况下,我使用的是 int;如果我不写一行,我将我的标志升为 1,否则我的标志永久为 0。当我的标志等于 1 时,这意味着我不想写后面的行。这是非常常见和有用的,尤其是在低级语言中,也许不是最好的选择。我希望我说得更清楚^^
    • 好的...谢谢...这确实让我清楚...至少我知道为什么...谢谢
    【解决方案2】:

    优化方案:

    with open('raw.txt', 'r') as fin, open('clean.txt', 'w') as fout:
        string_c_pat = re.compile(r'\s+stringC')
        pat = re.compile(r"\s+(stringA|stringB|stringC)")
    
        for line in fin:    # traversing file as iterator 
            if string_c_pat.match(line):
                next(fin)   # skip `stringC` line and jump to next line
            if not pat.match(line):
                fout.write(line)
    

    使用re.compile() 并保存生成的正则表达式 使用表达式时,对象的重用效率更高 在一个程序中多次。

    【讨论】:

    • 我同意该解决方案听起来更加优化,但您假设它只需要在 stringC 之后跳过。如果重点是删除字符串 A / B 或 C 之后的下一个空行,那么如果我没记错的话,那应该行不通
    • @Nqsir,我没有看到关键行与 OP 输入中的“stringA、stringB 和 stringC”不同,OP 可能会详细说明,如果这可能很关键
    • 我理解这个问题的方式让我假设:“分隔符应该是任何 stringA/B/C”,但我完全同意将分隔符放在 stringC 上的输入是正确的选择。跨度>
    • 嗨,先生...这个解决方案有效,但是当我想删除顶部和底部的空行时...我收到错误 TypeError: 'file' object has no attribute 'getitem'... .. 我添加..... for line in fin [6:-2]
    • @chenoi,你为什么在这种情况下使用fin[6:-2]
    猜你喜欢
    • 2011-04-25
    • 2017-04-18
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 2013-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多