2

ファイル内の特定の形式のすべての行を空白に置き換えようとしています。つまり、number/number/number (日付など) および number:number (時刻など) の行を "" に置き換えます。古いファイルから読み取り、スクラブしたバージョンを新しいファイルとして保存したい。

これは私がこれまでに持っているコードです(私はそれがかなりずれていることを知っています):

old_file = open("old_text.txt", "r")
new_file = open("new_text.txt", "w")

print (old_file.read())

for line in old_file.readlines():
    cleaned_line = line.replace("%/%/%", "")
    cleaned_line = line.replace("%:%", "")
    new_file.write(cleaned_line)

old_file.close
new_file.close

助けてくれてありがとう、ベン

4

2 に答える 2

2

ファイル内の特定の形式のすべての行を空白に置き換えようとしています。つまり、number/number/number (日付など) および number:number (時間など) の行を "" に置き換えます。

str.replaceを使用してパターンやフォーマットに一致させることはできません。リテラル文字列のみに一致させてください。

パターンを照合するには、ある種のパーサーが必要です。このようなパターンの場合、標準ライブラリに組み込まれている正規表現エンジンreは十分強力ですが、パターンの正規表現の書き方を学ぶ必要があります。リファレンス ドキュメントと正規表現 HOWTOは、基本を既に知っている場合に最適です。そうでない場合は、他の場所でチュートリアルを検索する必要があります。

とにかく、これを行う方法は次のとおりです(途中でいくつかの他のことを修正します。それらのほとんどはLego Stormtrooprによって説明されています):

import re

with open("old_text.txt") as old_file, open("new_text.txt", "w") as new_file:
    for line in old_file:
        cleaned_line = re.sub(r'\d+/\d+/\d+', '', line)
        cleaned_line = re.sub(r'\d+:\d+', '', cleaned_line)
        new_file.write(cleaned_line)

cleaned_lineまた、 2番目に使用したことに注意してくださいsub。元のコードのように、もう一度使用lineすると、最初の置換の結果が失われます。

あなたの問題の正確な定義を知らなければ、これがまさにあなたが望んでいることを約束することはできません. パターン番号/番号/番号を含むすべての行を空白にし、そのパターン以外のすべての行を空白にし、そのパターンだけを空白にして残りの行をそのままにしますか? これらはすべて を使用して実行可能であり、非常に簡単reですが、すべての方法が少し異なります。


少しトリッキーにしたい場合はre.sub、一度に 1 つずつ繰り返すのではなく、単一の式を使用して、一致するすべての行を一度に空白行に置き換えることができます。これは、正規表現が少し複雑であるのに対し、Python コードが少し単純であることを意味し、おそらく中サイズのファイルではパフォーマンスが向上するが、巨大なファイルではパフォーマンスが低下する (および上限が高くなる) ことを意味します。適切な式を自分で記述する方法がわからず、パフォーマンスのボトルネックを修正する必要がない場合は、明示的なループを使用します。

于 2013-10-02T00:28:34.623 に答える
0

まず、forループが理由もなくインデントされたインデントの問題があります。次に、readシークしたファイルを最後まで検索するとすぐに、読み取る行がなくなります。最後に、このwithコマンドを使用すると、ファイルを開いてその変数名を宣言し、手動で閉じることを心配することなく、エラーまたは最後まで読み取ったためにファイルを閉じることができます。

ただし、実際のロジックを実行するには、おそらく正規表現を使用する必要があります。re.search()パターンを見つけるために使用できます

  • \d+:\d+任意の数の Digits 、コロンおよび任意の数の Digits
  • \d+\/\d+\/d+任意の数の数字の 3 つのロットで、/その間にリテラルがあります。

あなたが望むコードはこれに近いです:

import re
with open("old_text.txt", "r") as oldfile, open("new_text.txt", "w") as new_file:
    for line in old_file:
        # This will match if this pattern is anywhere in the line
        if re.search("\d+:\d+", line) is not None:
            line = ""
        # This will match if this pattern is anywhere in the line
        if re.search("\d+\/\d+\/d+", line) is not None:
            line = ""
        new_file.write(line)

行頭でのみ一致させたい場合は、re.match()おそらくより良い選択です。

ここでは、2 つのファイルでブロックを宣言し、 をループしてold_file、各行を消去し、 に書き込みnew_fileます。最後にold_file達すると、すべてのファイルがきれいに閉じられます。いずれかのファイルが見つからない場合、またはエラーが発生した場合、with ブロックはこれらをキャッチし、すべてを適切に解放します。

于 2013-10-02T00:16:41.457 に答える