7

我需要解析一个包含 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...

我需要从中提取特定标签(例如,来自 35= 的“A”,或来自 11= 的“blahblah”),并忽略所有其他内容 - 基本上我需要忽略“35 = A”之前的任何内容,以及之后的任何内容到“11 = blahblah”,然后忽略之后的任何内容等。

我确实知道有一个库可以解析每个标签(http://source.kentyde.com/fixlib/overview),但是,如果可能的话,我希望在这里使用正则表达式的简单方法,因为我真的只需要几个标签。

正则表达式中是否有提取我需要的标签的好方法?

干杯,维克多

4

3 回答 3

9

无需拆分“\x01”然后正则表达式然后过滤。如果您只想要标签 34,49 和 56(MsgSeqNum、SenderCompId 和 TargetCompId),您可以使用正则表达式:

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

如果您知道您的发件人没有可能导致任何简单正则表达式中的错误的嵌入数据,那么像这样的简单正则表达式将起作用。具体来说:

  1. 没有原始数据字段(实际上是数据长度和原始数据的组合,例如 RawDataLength、RawData (95/96) 或 XmlDataLen、XmlData (212,213)
  2. 没有 unicode 字符串的编码字段,如 EncodedTextLen、EncodedText (354/355)

处理这些情况需要大量额外的解析。我使用自定义 python 解析器,但即使您在上面引用的 fixlib 代码也会出错。但是,如果您的数据没有这些异常,则上面的正则表达式应该返回您所需字段的一个很好的字典。

编辑:我保留了上面的正则表达式,但应该对其进行修改,以便最终匹配元素为(?=\x01). 可以在@tropleee 的答案中找到解释。

于 2012-01-17T21:34:50.813 回答
1

^A 实际上是 \x{01},这就是它在 vim 中的显示方式。在 perl 中,我通过在十六进制 1 上拆分然后在“=”上拆分来完成此操作,在第二次拆分时,数组的值 [0] 是标签,值 [1] 是值。

于 2011-12-29T19:05:28.510 回答
0

使用正则表达式工具,如 expresso 或 regexbuddy。
为什么不拆分^A然后匹配([^=])+=(.*)每个将它们放入哈希中?您还可以使用默认情况下不会添加您不感兴趣的标签并且对您感兴趣的所有标签都有影响的开关进行过滤。

于 2011-11-21T05:37:45.313 回答