2011-11-21 86 views
6

我需要解析包含FIX協議消息的日誌文件。解析正則表達式中的FIX協議?

每一行都包含頭信息(時間戳,日誌記錄級別,端點),後跟一個FIX有效載荷。

我用正則表達式來將頭信息解析成命名組。例如:

<?P<datetime>\d{2}/\d{2}/\d{2} \d{2}:\d{2}:\d{2}.\d{6}) (?<process_id>\d{4}/\d{1,2})\s*(?P<logging_level>\w*)\s*(?P<endpoint>\w*)\s* 

然後我來到了FIX有效載荷本身(^ A是每個標籤之間的分隔符),例如:

8=FIX.4.2^A9=61^A35=A...^A11=blahblah... 

我需要從這個(如「A」從提取特定標籤35 =或從11 =開始的「blahblah」),並忽略所有其他的東西 - 基本上我需要在「35 = A」之前忽略任何內容,以及在「11 = blahblah」之後的任何內容,然後忽略任何內容等。

我知道那裏有一個庫可能能夠解析每一個標籤(http://source.kentyde.com/fixlib/overv但是,如果可能的話,我希望在這裏使用正則表達式,因爲我真的只需要幾個標籤。

有沒有在正則表達式中提取我需要的標籤的好方法?

乾杯, 維克多

回答

0

使用像快報或使用RegexBuddy正則表達式的工具。
你爲什麼不分裂^A然後匹配([^=])+=(.*)爲每一個把他們放進一個散列?您也可以使用開關進行過濾,默認情況下不會添加您不感興趣的標籤,並且對您感興趣的所有標籤有所降低。

1

^A實際上是\ x {01},這就是它在vim中的表現。在perl中,我通過十六進制1進行分割,然後在「=」分割,在第二個分割中,數組的值[0]是標籤,值[1]是值。

9

不需要分割「\ x01」然後regex然後過濾。如果你想只是標籤34,49和56(MsgSeqNum,SenderCompId和TargetCompId),你可以正則表達式:如果你知道你的發件人沒有嵌入了可能導致錯誤的數據

dict(re.findall("(?:^|\x01)(34|49|56)=(.*?)\x01", raw_msg)) 

這樣簡單的正則表達式將工作任何簡單的正則表達式。具體做法是:

  1. 否原始數據字段(實際上數據的組合Len和像RawDataLength,RAWDATA(95/96)或XmlDataLen,XMLDATA原始數據(212213)
  2. 爲Unicode字符串等EncodedTextLen,EncodedText無編碼欄(355分之354)

處理這些案件需要很多額外的解析中,我使用自定義的Python語法分析器,但即使你上面提到的fixlib代碼獲取這些情況下是錯誤的。但是,如果你的數據是明確這些異常上面的正則表達式應該會返回所需字段的一個很好的字典。

編輯:我已經保留了上述正則表達式,但應該修改,以便最終匹配元素爲(?=\x01)。解釋可以在@ tropleee的answer here中找到。

+2

這是比接受的更好的答案。當然,你需要考慮「len」字段。每個人都會忘記這些!另外,FIX消息可以包含換行符(即在標籤58中),所以你需要使用re.DOTALL來確保。 – noahlz

+2

正如在[這個問題](http://stackoverflow.com/questions/31198950/parsing-fix-message-in-regex/31199578#31199575)解釋,這種解決方案有一個錯誤 - 它會失敗,當兩場比賽是鄰。 – tripleee