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)
看起来有些字段与正则表达式没有正确匹配.
这有什么问题?
问题是由于\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)
尾随\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)