1

こんにちは、600Mb のファイルを処理しています。私は以下のコードを書きました。私がやっていることは、タグ間のデータでキーワードを検索し、 <dest>存在する場合は都市タグを<dest>タグに追加することでした。小さなデータセットでは問題なく動作しましたが、大きなファイルでプログラムを実行すると、MEMORY ERROR がスローされます。returnステートメントを使用するとこのエラーが発生すると思いますが、これif conditionを解決する方法を教えてください。

import re

def casp ( tx ):
    def tbcnv( st ):
        ct = ''
        prt = re.compile(r"(?i)(Slip Copy,.*?\))", re.DOTALL|re.M)
        val = re.search(prt, st)
        try:
            ct = val.group(1)
            if re.search(r"(?i)alaska", ct):
                jval = "Alaska"
                print jval
                if jval:
                    prt = re.compile(r"(?i)(.*?<dest.*?>)", re.DOTALL|re.M)
                    vl = re.sub(prt, "\\1\n" +  "<city>" + jval + "</city>" + "\n" ,st)
                    return vl
                else:
                    return st
            else:
                return st
        except:
            print "Not available"
            return st   

    pt = re.compile("(?i)(<dest.*?</dest>)", re.DOTALL|re.M)
    t = re.sub(pt, lambda m: tbcnv(m.group(1)), tx)
    return t

with open('input.txt', 'r') as content_file:
    content = content_file.read()
    pt = re.compile(r"(?i)<Lrlevel level='3'>(.*?)</Lrlevel>", re.DOTALL|re.M)
    content = re.sub(pt,lambda m: "<Lrlevel level='3'>" + casp(m.group(1) + "</Lrlevel>" ), content)

with open('out.txt', 'w') as out_file:
    out_file.write(content)
4

1 に答える 1

2

returnの直前のステートメントを削除すると、によって作成expectされる文字列re.sub()ははるかに小さくなります。

ファイル サイズの 3 倍のメモリ使用量を取得しています。つまり、2GB を (それ以上) 持っていない場合は MemoryError が発生します。これはここでは合理的です --- または、少なくともその理由は推測できます。それがどのように機能するかre.sub()です。

これは、上記のコメントで説明したように、何らかの形で間違ったツールを使用していることを意味します。lxml のような完全な xml 処理ツールを使用するか、正規表現を使用したい場合は、メモリ内の文字列全体を必要としない方法を見つける必要があります。または、少なくともそれを呼び出すことはありませんre.sub()(たとえば、tx変数だけが入力である大きな文字列を含むことがありpt.search(tx, startpos)、ループで実行し、変更する場所を見つけて、 の部分ごとに記述しますtx)。

于 2013-03-09T01:39:28.597 に答える