2 つの具体的な文字列を含む 2 つの行の間にあるものを削除する方法はありますか?
つまり、次のテキストを含むテキストファイルで「天国」と「地獄」の間にあるものをすべて削除したい:
I'm in heaven
foobar
I'm in hell
スクリプト/関数を実行した後、テキスト ファイルが空になるように求めています。
フラグを使用して、書き込み中かどうかを示します。
from __future__ import with_statement
writing = True
with open('myfile.txt') as f:
with open('output.txt') as out:
for line in f:
if writing:
if "heaven" in line:
writing = False
else:
out.write(line)
elif "hell" in line:
writing = True
os.remove('myfile.txt')
os.rename('output.txt', 'myfile.txt')
編集
extraneonがコメントで指摘したように、要件は 2 つの具体的な文字列の間の行を削除することです。つまり、2 番目の (終了) 文字列が見つからない場合は、何も削除しないでください。これは、行のバッファーを保持することで実現できます。終了文字列が見つかった場合、バッファは破棄"I'm in hell"
されますが、見つからずにファイルの終わりに達した場合は、内容全体をファイルに書き込む必要があります。
例:
I'm in heaven
foo
bar
終了タグがなく、質問にはbetween two linesと記載されているため、コンテンツ全体を保持する必要があります。
完成させるために、これを行う例を次に示します。
from __future__ import with_statement
writing = True
with open('myfile.txt') as f:
with open('output.txt') as out:
for line in f:
if writing:
if "heaven" in line:
writing = False
buffer = [line]
else:
out.write(line)
elif "hell" in line:
writing = True
else:
buffer.append(line)
else:
if not writing:
#There wasn't a closing "I'm in hell", so write buffer contents
out.writelines(buffer)
os.remove('myfile.txt')
os.rename('output.txt', 'myfile.txt')
「削除」とは、「入力ファイルをその場で書き換える」(またはそうしているように見せる;-)ことを意味するように見えます。その場合、fileinput.inputが役立ちます:
import fileinput
writing = True
for line in fileinput.input(['thefile.txt'], inplace=True):
if writing:
if 'heaven' in line: writing = False
else: print line,
else:
if 'hell' in line: writing = True
正規表現を使用すると、次のようなことができます。私はまだ多くのPythonを学んでいるので、おそらくもっと効率的な方法がありますが、これはうまくいくはずです.
import re
f = open('hh_remove.txt')
lines = f.readlines()
pattern1 = re.compile("heaven",re.I)
pattern2 = re.compile("hell",re.I)
mark1 = False
mark2 = False
for i, line in enumerate(lines):
if pattern1.search(line) != None:
mark1 = True
set1 = i
if pattern2.search(line) != None:
mark2 = True
set2 = i+1
if ((mark1 == True) and (mark2 == True)):
del lines[set1:set2]
mark1 = False
mark2 = False
f.close()
out = open('hh_remove.txt','w')
out.write("".join(lines))
out.close()
申し訳ありませんが、これは宿題のように聞こえます。これらに関するポリシーがあります: https://meta.stackexchange.com/questions/10811/homework-on-stackoverflow
ただし、私が言えることは、@nosklo が書いた機能はすべての Python 2.5.x (またはそれ以降) で利用できますが、それを有効にするには十分な Python を学ぶ必要があるということです。:-)
str.find()
私の解決策は、またはstr.index()
(またはそれらの2つの相対的なもの)を使用して不要なものを取り除いた新しい文字列を作成することです。
頑張ってください!
下記参照。大丈夫かどうかはわかりませんが、問題なく動いているようです。
import re,fileinput,os
for path, dirs, files in os.walk(path):
for filename in files:
fullpath = os.path.join(path, filename)
f = open(fullpath,'r')
data = f.read()
patter = re.compile('Im in heaven.*?Im in hell', re.I | re.S)
data = patter.sub("", data)
f.close()
f = open(fullpath, 'w')
f.write(data)
f.close()
とにかく、実行すると空白行が残ります。つまり、この機能がある場合:
public function preFetchAll(Doctrine_Event $event){
//Im in heaven
$a = sfContext::getInstance()->getUser()->getAttribute("passw.formulario");
var_dump($a);
//Im in hell
foreach ($this->_listeners as $listener) {
$listener->preFetchAll($event);
}
}
スクリプトを実行すると、次のようになります。
public function preFetchAll(Doctrine_Event $event){
foreach ($this->_listeners as $listener) {
$listener->preFetchAll($event);
}
}
ご覧のとおり、"public..." と "foreach..." の間に空の行があります。
なんで?
ハビ