解析正则表达式中的FIX消息

Joh*_*nyy 4 regex fix-protocol

在正则表达式中找到了Parsing FIX协议的第二个答案非常好,所以我试了一下.

这是我的代码.

new_order_finder1 = re.compile("(?:^|\x01)(11|15|55)=(.*?)\x01")
new_order_finder2 = re.compile("(?:^|\x01)(15|55)=(.*?)\x01")
new_order_finder3 = re.compile("(?:^|\x01)(11|15|35|38|54|55)=(.*?)\x01")

if __name__ == "__main__":
    line = "20150702-05:36:08.687 : 8=FIX.4.2\x019=209\x0135=D\x0134=739\x0149=PINE\x0152=20150702-05:36:08.687\x0156=CSUS\x011=KI\x0111=N09080243\x0115=USD\x0121=2\x0122=5\x0138=2100\x0140=2\x0144=126\x0148=AAPL.O\x0154=1\x0155=AAPL.O\x0157=DMA\x0158=TEXT\x0160=20150702-05:36:08.687\x01115=Tester\x016061=9\x0110=087\x01"
    fields = dict(re.findall(new_order_finder1, line))
    print(fields)

    fields2 = dict(re.findall(new_order_finder2, line))
    print(fields2)

    fields3 = dict(re.findall(new_order_finder3, line))
    print(fields3)
Run Code Online (Sandbox Code Playgroud)

这是输出

{'11': 'N09080243', '55': 'AAPL.O'}
{'55': 'AAPL.O', '15': 'USD'}
{'35': 'D', '38': '2100', '11': 'N09080243', '54': '1'}
Run Code Online (Sandbox Code Playgroud)

看起来有些字段与正则表达式没有正确匹配.

这有什么问题?

nha*_*tdh 5

问题是由于\x01最后消耗了\x01分隔符,这导致模式在与刚匹配的键值对相邻的键值对上总是失败,因为没有一个(?:^|\x01)可以匹配。

以您输入的此子字符串为例,与匹配new_order_finder3

\x0154=1\x0155=AAPL.O\x01
------------
            X
Run Code Online (Sandbox Code Playgroud)

如您所见,在成功匹配键值对之后54=1,它也消耗了\x01,并且相邻键值对永远不会匹配。

有多种方法可以解决此问题。一种解决方案是将\x01the结尾放在一个预先声明中,以便我们可以确保\x01在不使用键值对的情况下结束该键值对:

new_order_finder3 = re.compile("(?:^|\x01)(11|15|35|38|54|55)=(.*?)(?=\x01)")
Run Code Online (Sandbox Code Playgroud)

现在,输出包含所有预期字段:

{'11': 'N09080243', '38': '2100', '15': 'USD', '55': 'AAPL.O', '54': '1', '35': 'D'}
Run Code Online (Sandbox Code Playgroud)


tri*_*eee 5

尾随\x01消耗你想要匹配的东西.正则表达式匹配器将在上一个匹配的事物之后继续进行下一个匹配.

通过前瞻,修复很容易.只需更换最后\x01(?=\x01).

import re

new_order_finder3 = re.compile("(?:^|\x01)(11|15|35|38|54|55)=(.*?)(?=\x01)")

if __name__ == "__main__":
    line = "20150702-05:36:08.687 : 8=FIX.4.2\x019=209\x0135=D\x0134=739\x01"\
        "49=PINE\x0152=20150702-05:36:08.687\x0156=CSUS\x011=KI\x01" \
        "11=N09080243\x0115=USD\x0121=2\x0122=5\x0138=2100\x0140=2\x01" \
        "44=126\x0148=AAPL.O\x0154=1\x0155=AAPL.O\x0157=DMA\x0158=TEXT\x01" \
        "60=20150702-05:36:08.687\x01115=Tester\x016061=9\x0110=087\x01"
    fields3 = dict(re.findall(new_order_finder3, line))
    print(fields3)
Run Code Online (Sandbox Code Playgroud)