Regex 解析正则表达式中的修复消息

Regex 解析正则表达式中的修复消息,regex,fix-protocol,Regex,Fix Protocol,我发现第二个答案很好,所以我试了一下 这是我的密码 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

我发现第二个答案很好,所以我试了一下

这是我的密码

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)
这是输出

{'11': 'N09080243', '55': 'AAPL.O'}
{'55': 'AAPL.O', '15': 'USD'}
{'35': 'D', '38': '2100', '11': 'N09080243', '54': '1'}
看起来有些字段没有与正则表达式正确匹配


这里的问题是什么?

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

以输入的这个子字符串为例,与
新订单\u finder3
匹配:

\x0154=1\x0155=AAPL.O\x01
------------
            X
如您所见,在它设法匹配键值对
54=1
之后,它还消耗
\x01
,并且相邻的键值对永远无法匹配

解决此问题的方法不止一种。一种解决方案是将
\x01
放在前瞻断言的末尾,这样我们就可以确保
\x01
在不使用键值对的情况下结束键值对:

new_order_finder3 = re.compile("(?:^|\x01)(11|15|35|38|54|55)=(.*?)(?=\x01)")
输出现在包含所有预期字段:

{'11': 'N09080243', '38': '2100', '15': 'USD', '55': 'AAPL.O', '54': '1', '35': 'D'}

尾随的
\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)