2

なんらかの理由で、プログラムが57802レコードのファイルの反復処理を停止するという問題が発生しました。ハートビートセクションを挿入して、それがどの行にあるかを確認できるようにしましたが、それが役に立ったのですが、なぜここで停止するのかがわかりません。メモリの問題だと思いましたが、6GBのメモリコンピュータで実行しただけで停止しました。

私が下でやっていることをするためのより良い方法はありますか?私の目標は、ファイルを読み取ることです(ファイルを送信する必要がある場合は、15 MBのテキストログを使用できます)。正規表現に基づいて一致するものを見つけ、一致する行を印刷します。もっと来ますが、それは私が得た限りです。私はPython2.6を使用しています

どんなアイデアでも助けになり、コメントもコーディングできます!私はPythonの初心者で、まだ学習中です。

import sys, os, os.path, operator
import re, time, fileinput

infile = os.path.join("C:\\","Python26","Scripts","stdout.log")

start = time.clock()

filename  = open(infile,"r")

match = re.compile(r'(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}),\d{3} +\w+ +\[([\w.]+)\] ((\w+).?)+:\d+ - (\w+)_SEARCH:(.+)')

count = 0
heartbeat = 0
for line in filename:
    heartbeat = heartbeat + 1
    print heartbeat
    lookup = match.search(line)
    if lookup:
        count = count + 1
        print line
end = time.clock()
elapsed = end-start
print "Finished processing at:",elapsed,"secs. Count of records =",count,"."

filename.close()

これは、失敗する行57802です。

2010-08-06 08:15:15,390 DEBUG [ah_admin] com.thg.struts2.SecurityInterceptor.intercept:46 - Action not SecurityAware; skipping privilege check.

これは一致する行です:

2010-08-06 09:27:29,545 INFO  [patrick.phelan] com.thg.sam.actions.marketmaterial.MarketMaterialAction.result:223 - MARKET_MATERIAL_SEARCH:{"_appInfo":{"_appId":21,"_companyDivisionId":42,"_environment":"PRODUCTION"},"_description":"symlin","_createdBy":"","_fieldType":"GEO","_geoIds":["Illinois"],"_brandIds":[2883],"_archived":"ACTIVE","_expired":"UNEXPIRED","_customized":"CUSTOMIZED","_webVisible":"VISIBLE_ONLY"}

最初の5行だけのサンプルデータ:

2010-08-06 00:00:00,035 DEBUG [] com.thg.sam.jobs.PlanFormularyLoadJob.executeInternal:67 - Entered into PlanFormularyLoadJob: executeInternal
2010-08-06 00:00:00,039 DEBUG [] com.thg.ftpComponent.service.JScapeFtpService.open:153 - Opening FTP connection to sdrive/hibbert@tccfp01.hibbertnet.com:21
2010-08-06 00:00:00,040 DEBUG [] com.thg.sam.email.EmailUtils.sendEmail:206 - org.apache.commons.mail.MultiPartEmail@446e79
2010-08-06 00:00:00,045 DEBUG [] com.thg.sam.services.OrderService.getOrdersWithStatus:121 - Orders list size=13
2010-08-06 00:00:00,045 DEBUG [] com.thg.ftpComponent.service.JScapeFtpService.open:153 - Opening FTP connection to sdrive/hibbert@tccfp01.hibbertnet.com:21
4

6 に答える 6

7

問題を引き起こす入力行はどのように見えますか?それを印刷してみます。これが実行されている間、CPUが固定されていると思われます。

ネストされた正規表現は、すぐに一致しない場合、パフォーマンスが非常に悪くなる可能性があります。

((\w+).?)+:

:が含まれていないが、かなり長い文字列を想像してみてください。正規表現が\wと。の間の単語文字を区切る方法のすべての組み合わせを試みるため、バックトラックの世界に行き着きます。そして、可能な限りあらゆる方法でそれらをグループ化しようとします。パターンをより具体的にすることができれば、大きな成果が得られます。

于 2010-09-01T00:26:15.493 に答える
2

あなたの問題は間違いなく@paulrubelが指摘した部分です:

((\w+).?)+:\d+

サンプルデータを追加したので、がリテラルドットと一致することになっていることは明らかです。つまり、.エスケープする必要があります(\.)。また、括弧の内側のセットは必要ありません。外側のセットはキャプチャされないようにする必要がありますが、それがあなたを殺している基本的な構造です。諦める前に試さなければならない単語文字とドットの配置が多すぎます。他の行はすべて、正規表現のその部分が試行される前に失敗します。そのため、問題はありません。

私がRegexBuddyで試してみると、あなたの正規表現は186ステップで良い行と一致し、1,000,000ステップ後に行57802での試用をあきらめます。ドットをエスケープすると、適切な行は一致するのに90ステップしかかかりませんが、それでも57802行でタイムアウトになります。しかし、正規表現の一部は単語の文字とドットにしか一致しないことがわかりました。可能な限りすべてを消費したら、次のビットは一致する必要が:\d+あります。そうでなければ、他の取り決めを試してみても意味がないことを私は知っています。アトミックグループを使用して、気にしないように指示できます。

(?>(?:\w+\.?)+):\d+

この変更により、正常な行は83ステップで一致し、行57802は障害を報告するために66ステップしか実行しません。ただし、アトミックグループを使用できるとは限らないため、正規表現を、一致するテキストの実際の構造に一致させるようにしてください。この場合、Javaクラス名(いくつかの単語文字、それに続く0個以上の(ドットといくつかの単語文字)のインスタンス)、それに続くコロンと行番号のように見えるものと一致します。

\w+(?:\.\w+)*:\d+

これを正規表現に接続すると、80ステップで適切な行と一致し、67ステップで行57802を拒否します。アトミックグループは必要ありません。

于 2010-09-01T08:50:41.643 に答える
1

正規表現をコンパイルしましたが、使用したことはありませんか?

lookup = re.search(match,line)

する必要があります

lookup = match.search(line)

そして、あなたは使用する必要がありますos.path.join()

infile = os.path.join("C:\\","Python26","Scripts","stdout.log")

アップデート:

正規表現をより単純にすることができます。日付のタイムスタンプを確認するだけです。それ以外の場合は、正規表現をまったく使用しないでください。日付と時刻が行頭から始まると言います

for line in open("stdout.log"):
    s = line.split()
    D,T=s[0],s[1]
    # use the time module and strptime to check valid date/time
    # or you can split "-" on D and T and do manual check using > or < and math
于 2010-09-01T00:36:54.063 に答える
1

パターンには、固定文字列SEARCH_と、正規表現エンジンを実際にハンマーで叩く複雑な式(キャプチャを含む)が含まれています。ただし、キャプチャされたテキストには何もしないので、知りたいのは'一致するかどうかだけです。 ? '

各行の固定パターンを検索する方が簡単で迅速な場合があります。

if '_SEARCH:' in line:
    print line
    count += 1
于 2010-09-01T18:28:04.173 に答える
0

pdbを使用してみてください。pdb.set_trace()停止する直前にハートビートを入力すると、停止している特定の行を確認して、コードの各行がその行で何をするかを確認できます。

編集:pdbの使用例:

import pdb
for i in range(50):
    print i
    if i == 12:
        pdb.set_trace()

そのスクリプトを実行すると、次のようなものが得られます。

0
1
2
3
4
5
6
7
8
9
10
11
12
> <stdin>(1)<module>()
(Pdb)

これで、i=12のコンテキストからPython式を評価できます。

(Pdb) print i
12

それを使用しますがpdb.set_trace()、ハートビートをインクリメントした後、ループに入れますheartbeat == 57802。次に、で行を印刷しp lineたり、正規表現検索の結果をで印刷したりできますp match.search(line)

于 2010-09-01T00:05:56.727 に答える
0

とにかくメモリの問題かもしれません。巨大なファイルの場合は、次のfileinputように代わりにモジュールを使用することをお勧めします。

import fileinput
for line in fileinput.input([infile]):
    lookup = re.search(match, line)
     # etc.
于 2010-09-01T00:12:28.383 に答える