0

私は Python 2.4 を使用しており、Python の初心者であり、一般的なプログラミングと正規表現を使用しています。現在、ストリーム A とストリーム B の 2 つの別々のストリーム (またはデータセット/ファイル) の行を出力する大きなモジュールがあります。ストリーム A とストリーム B を比較して、ストリーム B の文字列が任意の行内で一致するかどうかを確認しようとしています。ストリーム A のすべての一致するコンテンツとすべての一致しないコンテンツを 2 つの別個のオブジェクトとして返したいと考えています。以下の太字の私の問題をご覧ください。この問題を解決する方法やベストプラクティスの推奨事項を知っている人はいますか?

これまでのところ、このコードを使用して、ストリーム B (「リアルタイム」) をリスト (「正規表現」) に変換し、そのリストを正規表現のグループ (「結合」) に変換しました。

モジュールにすべてのコードを含めているわけではなく、行き詰まっている部分だけを含めていることに注意してください

regex = re.compile(r'.*\[(\d{2}:\d{2}:\d{2}\.\d{6})\].*')
optsymbx = re.compile(r'\[(\d{2}:\d{2}:\d{2}\.\d{6})\][\s]+(trade),(S|B),(\d{1,}),(\w+)[\s]+([0-9A-Z]+),(\d+\.\d+)')
regexes = []

def realtimes():
    for x in realtrades():
        x = str(x)
        m = re.match(regex,x)
        if m:
            #regexes.append(str(m.groups()))
            yield str(m.groups())

#make contents of realtimes into group of regular expressions     
f = open(logfile,'r')
for x in realtimes():
    regexes.append(x)
combined = "(" + ")|(".join(regexes) + ")"

次に、ストリーム A (f の行) を調べ、次のように、各行を「結合」および 1 つの追加の正規表現基準 (「optsymbx」) と照合して、一致するかどうかを確認します。

# checking if any lines in the logfile match "optsymbx" and any regular expressions wihtin "combined"
f = open(logfile,'r')
for line in f:
    m = re.match(combined,line)
    mopt = re.match(optsymbx,line)
    if not m:
        if mopt:
            print line

問題は、ストリーム A と B が非常に大きいことです。ストリーム A には 100,000 を超える行が含まれ、ストリーム B には数千の行があります。したがって、ストリーム B のコンテンツを正規表現のグループ (「結合」) に変換すると、100 個の名前付きグループの容量を超え、エラーが発生します 。ストリーム B のコンテンツを 100 未満の名前付きグループに分割します。

Traceback (most recent call last):
  File "badtrades.py", line 121, in ?
    m = re.match(combined,line)
  File "/usr/lib64/python2.4/sre.py", line 129, in match
    return _compile(pattern, flags).match(string)
  File "/usr/lib64/python2.4/sre.py", line 225, in _compile
    p = sre_compile.compile(pattern, flags)
  File "/usr/lib64/python2.4/sre_compile.py", line 506, in compile
    raise AssertionError(
AssertionError: sorry, but this version only supports 100 named groups

結合されたサンプルデータ (ストリーム B から派生):

    ["('09:50:31.458370',)", **"('09:50:31.458370',)"**, "('09:50:48.343785',)", "('09:50:48.449219',)", "('09:50:48.449219',)", "('09:50:48.449219',)", "('09:50:48.449219',)", "('09:51:01.986971',)", "('09:51:01.986971',)", "('09:51:01.986971',)", "('09:51:34.543147',)", "('09:52:14.688349',)", "('09:52:14.688349',)", "('09:52:14.688349',)", "('09:52:14.688349',)", "('09:52:19.700134',)", "('09:53:06.696156',)", "('09:53:06.696156',)", "('09:53:06.696156',)", "('09:53:06.696156',)", "('09:53:06.696156',)", "('09:53:06.696156',)", "('09:53:06.696156',)", "('09:53:06.696156',)", "('09:54:39.295261',)", "('09:54:39.295261',)", "('09:54:44.883143',)", "('09:54:44.883143',)", "('09:54:44.883143',)", "('09:54:44.883143',)", "('09:55:17.750226',)", "('09:55:17.750226',)", "('09:55:17.750226',)", "('09:55:17.750226',)", "('09:55:17.750226',)", "('09:55:17.750226',)", "('09:55:17.750226',)", "('09:55:17.750226',)", "('09:55:17.750226',)", "('09:55:19.767099',)", "('09:55:26.750094',)", "('09:55:26.750094',)", "('09:55:29.195194',)", "('09:55:29.195194',)", "('09:55:29.195194',)", "('09:55:29.195194',)", "('09:55:29.195194',)", "('09:55:29.722747',)", "('09:56:38.809658',)", "('09:56:38.809658',)", "('09:57:38.444653',)", "('09:57:38.444653',)", "('09:57:38.444653',)", "('09:57:38.444653',)", "('09:57:38.444653',)", "('09:57:38.444653',)", "('09:57:38.444653',)", "('09:57:38.444653',)", "('09:57:38.444653',)", "('09:57:38.444653',)", "('09:57:38.444653',)", "('09:57:38.444653',)", "('09:57:38.444653',)", "('09:57:38.444653',)", "('09:57:38.444653',)", "('09:58:37.573746',)", "('09:58:37.573746',)", "('09:58:37.573746',)", "('09:59:02.185210',)", "('09:59:09.245981',)", "('09:59:33.619633',)", "('09:59:33.619633',)", "('09:59:33.619633',)", "('09:59:33.619633',)"]

ログファイルからのサンプル データ (ストリーム A):

[09:49:52.515951] T,AAPL  130518C00450000,1,32.05
[09:49:53.568816] T,AAPL  130328P00455000,30,1.09
[09:49:53.811441] trade,S,2,AAPL  130328C00470000,4.75
[09:49:53.811447] trade,B,95,AAPL,468.69
--
[09:50:31.241441] T,AAPL  130328P00430000,3,0.08
[09:50:31.385327] T,AAPL  130328P00455000,5,1.10
[09:50:31.385911] T,AAPL  130328P00455000,5,1.10
[09:50:31.458370] trade,B,2,AAPL  130328C00475000,2.80
[09:50:31.458373] trade,S,68,AAPL,468.46
--
[09:50:48.339322] T,AAPL  130328C00485000,8,0.92
[09:50:48.339341] T,AAPL  130328C00485000,1,0.92
[09:50:48.339357] T,AAPL  130328C00485000,9,0.92
[09:50:48.343785] trade,B,2,AAPL  130328C00465000,7.05
[09:50:48.343789] trade,S,118,AAPL,468.19

一致は次のようになります。

data A:  [09:50:31.458370] trade,B,2,AAPL  130328C00475000,2.80
data B:  [09:50:31.458370]

一致しない場合:

data A:  [09:49:53.811441] trade,S,2,AAPL  130328C00470000,4.75
data B:  #there is no timestamp from B which matches A
4

1 に答える 1

0

正規表現を忘れてください。各ストリームを噛むだけです。できる限り試合を進めて並べ替えます。擬似コード:

Using Streams A and B, and Objects Match and NoMatch
FETCH next Line of A into LineA
FETCH next Line of B into LineB
WHILE Neither stream is at end of file:
    WHILE TimeStamp in LineA < TimeStamp in LineB:
        ADD LineA to NoMatch
        FETCH next Line of A into LineA
    WHILE TimeStamp in LineA = TimeStamp in LineB:
        Add (LineA, LineB) to Match
        FETCH next Line of A into LineA
    FETCH next Line of B into LineB
WHILE A is not at End of File
    ADD LineA to NoMatch
    FETCH next Line of A into LineA

これは、A では繰り返しを処理しますが、B では処理しません。B で繰り返しを処理するには、過去の行のメモリを維持する必要があります。

Using Streams A and B, and Objects Match, NoMatch and Temp
FETCH next Line of A into LineA
FETCH next Line of B into LineB
WHILE Neither stream is at end of file:
    CLEAR Temp
    WHILE TimeStamp in LineA < TimeStamp in LineB:
        ADD LineA to NoMatch
        FETCH next Line of A into LineA
    WHILE TimeStamp in LineA = TimeStamp in LineB:
        ADD (LineA, LineB) to Match
        ADD LineA to Temp
        SET Temp Timestamp to LineA Timestamp
        FETCH next Line of A into LineA
    FETCH next Line of B into LineB
    WHILE TimeStamp in LineB = Temp TimeStamp:
        FOR Line IN Temp:
            ADD (Line, LineB) TO Match
        FETCH next Line of B into LineB 
WHILE A is not at End of File
    ADD LineA to NoMatch
    FETCH next Line of A into LineA

編集: EOF を決定する方法についてはあいまいでした。EOF が返され、空の文字列が返された後の読み取りを想定してみましょう (Python の場合と同様)。実装は次のように機能します。

Using Streams A and B, and Objects Match, NoMatch and Temp
FETCH next Line of A into LineA
FETCH next Line of B into LineB
WHILE Neither LineA nor LineB is an Empty String:
    CLEAR Temp
    WHILE LineA is not an Empty String, AND TimeStamp in LineA < TimeStamp in LineB:
        ADD LineA to NoMatch
        FETCH next Line of A into LineA
    WHILE LineA is not an Empty String, AND TimeStamp in LineA = TimeStamp in LineB:
        ADD (LineA, LineB) to Match
        ADD LineA to Temp
        SET Temp Timestamp to LineA Timestamp
        FETCH next Line of A into LineA
    FETCH next Line of B into LineB
    WHILE LineB is not an Empty String, AND TimeStamp in LineB = Temp TimeStamp:
        FOR Line IN Temp:
            ADD (Line, LineB) TO Match
        FETCH next Line of B into LineB 

//At this point, Either LineA is empty (meaning there are no more strings to match),
//or LineB is empty (meaning there are no more matches to find).  If the first is true,
//This loop will be skipped.  Otherwise, this loop will put what's left of A into the 
//Not Matched Object.
WHILE  LineA is not an Empty String:
    ADD LineA to NoMatch
    FETCH next Line of A into LineA
于 2013-03-25T20:36:11.200 に答える