2012-08-08 49 views
0

我已经检查并使用了各种示例,看起来我的问题比我所能找到的要复杂一些。我需要做的是搜索一个特定的字符串,然后删除下面的行并保持删除行直到找到另一个字符串。因此,一个例子是以下几点:删除match1之后只匹配到匹配2

a 
b 
color [ 
0 0 0, 
1 1 1, 
3 3 3, 
] #color 
y 
z 

这里,"color ["是MATCH1和"] #color"是MATCH2。那么需要的是以下几点:

a 
b 
color [ 
] #color 
y 
z 
+0

这将有助于确定哪些是“MATCH1”和“MATCH2”,也为您的显示输入一些相应的输出。还有其他任何约束(也可以通过输入/输出对来显示)。 – Levon 2012-08-09 13:16:53

回答

2

这个“简单易用”的代码示例会让你开始..你可以根据需要调整它。请注意,它会逐行处理文件,因此可以处理任何大小的文件。

start_marker = 'startdel' 
end_marker = 'enddel' 

with open('data.txt') as inf: 
    ignoreLines = False 
    for line in inf: 
     if start_marker in line: 
      print line, 
      ignoreLines = True 
     if end_marker in line: 
      ignoreLines = False    
     if not ignoreLines: 
      print line, 

它采用startdelenddel为“标记”的开始和结束数据的忽略。

更新

基于评论的请求修改后的代码,这将现在包括/打印包含“标志”的行。

鉴于这种输入数据(来自@drewk借用):

Beginning of the file... 
stuff 
startdel 
    delete this line 
    delete this line also 
enddel 
stuff as well 
the rest of the file... 

它产生:

Beginning of the file... 
stuff 
startdel 
enddel 
stuff as well 
the rest of the file... 
+0

这工作太棒了,但我需要保持搜索线'寻找这条线'和'直到找到这条线'。该代码当前也删除这些行。这是一个简单的修改吗? – 2012-08-08 01:06:47

+0

@ScottRichardson我更新了代码,给它一个旋转,看看它是否符合你的要求。 – Levon 2012-08-08 01:10:16

+0

嗨Levon,我尝试了新的代码,对我来说,它会打印'enddel'两行。 – 2012-08-08 17:10:22

1

您可以通过使用nongreedy *有一个正则表达式做到这一点。例如,假设你想同时保留"look for this line""until this line is found"线,并丢弃只在字里行间,你可以这样做:

>>> my_regex = re.compile("(look for this line)"+ 
...      ".*?"+ # match as few chars as possible 
...      "(until this line is found)", 
...      re.DOTALL) 
>>> new_str = my_regex.sub("\1\2", old_str) 

的几个注意事项:

  • re.DOTALL标志告诉Python “”可以匹配换行符 - 默认情况下,它匹配除换行符以外的任何字符
  • 圆括号定义了“编号匹配组”,稍后当我说“\ 1 \ 2”时确保我们不会丢弃第一行和最后一行。如果你确实想放弃其中的一个或两个,那么只要摆脱1和/或2。例如,保留第一个但不是最后一个使用my_regex.sub("\1", old_str);或摆脱都使用my_regex.sub("", old_str)

为了进一步的说明,请参阅:http://docs.python.org/library/re.html或搜索你喜欢的搜索引擎“非贪婪正则表达式”。

+0

嗨,爱德华,这个工作很完美,非常感谢!虽然我在模型测试文件中试过这个,但是直到明天我才能在实际的文件上尝试它。事实证明,我将使用它的文件将会非常大(> 10万行),并且将会有多达20个块需要删除。所以我的问题是这个代码对于包含很多行的文件是最有效的,并且这个代码是否会执行这个操作直到找到eof?再次感谢你。 – 2012-08-08 19:55:15

+0

这将取代所有的事件。但是,如果你的文件非常大,那么这可能不是最好的方法,因为你需要读入整个文件,处理它,然后写出结果。所以你可能想要采用更像Levon所建议的方法。 (在现代系统中,将100k行文件加载到内存中并非没有道理,但它当然不是最有效的方法。) – 2012-08-09 00:34:19

1

这工作:

s="""Beginning of the file... 
stuff 
look for this line 
    delete this line 
    delete this line also 
until this line is found 
stuff as well 
the rest of the file... """ 

import re 

print re.sub(r'(^look for this line$).*?(^until this line is found$)', 
      r'\1\n\2',s,count=1,flags=re.DOTALL | re.MULTILINE) 

打印:

Beginning of the file... 
stuff 
look for this line 
until this line is found 
stuff as well 
the rest of the file... 

您还可以使用单片要做到这一点:

mStart='look for this line' 
mStop='until this line is found' 
li=s.split('\n') 
print '\n'.join(li[0:li.index(mStart)+1]+li[li.index(mStop):]) 

相同的输出。

我喜欢re这个(是一个Perl家伙在心脏...)

+0

非常感谢大家! – 2012-08-08 01:27:56