0

2 つの具体的な文字列を含む 2 つの行の間にあるものを削除する方法はありますか?

つまり、次のテキストを含むテキストファイルで「天国」と「地獄」の間にあるものをすべて削除したい:

I'm in heaven
foobar
I'm in hell

スクリプト/関数を実行した後、テキスト ファイルが空になるように求めています。

4

5 に答える 5

3

フラグを使用して、書き込み中かどうかを示します。

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')
于 2010-04-05T17:01:19.377 に答える
1

「削除」とは、「入力ファイルをその場で書き換える」(またはそうしているように見せる;-)ことを意味するように見えます。その場合、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
于 2010-04-05T18:01:50.147 に答える
0

正規表現を使用すると、次のようなことができます。私はまだ多くの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()
于 2010-04-05T17:38:58.400 に答える
-1

申し訳ありませんが、これは宿題のように聞こえます。これらに関するポリシーがあります: https://meta.stackexchange.com/questions/10811/homework-on-stackoverflow

ただし、私が言えることは、@nosklo が書いた機能すべての Python 2.5.x (またはそれ以降) で利用できますが、それを有効にするには十分な Python を学ぶ必要があるということです。:-)

str.find()私の解決策は、またはstr.index()(またはそれらの2つの相対的なもの)を使用して不要なものを取り除いた新しい文字列を作成することです。

頑張ってください!

于 2010-04-05T17:36:09.613 に答える
-1

下記参照。大丈夫かどうかはわかりませんが、問題なく動いているようです。

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..." の間に空の行があります。

なんで?

ハビ

于 2010-04-05T18:55:48.697 に答える