Разбор протокола FIX в регулярных выражениях? - PullRequest
6 голосов
/ 21 ноября 2011

Мне нужно проанализировать файлы журналов, которые содержат сообщения протокола FIX.

Каждая строка содержит информацию заголовка (отметка времени, уровень ведения журнала, конечная точка), за которой следует полезная нагрузка FIX.

Я использовал regex для разбора информации заголовка на именованные группы. E.g.:

 <?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 = или «blahblah» из 11 =) и игнорировать все остальные вещи - в основном мне нужно что-то игнорировать до «35 = A», и что-нибудь после "11 = бла-бла", затем игнорируйте что-нибудь после этого и т. д.

Я знаю, что есть библиотеки, которые могут анализировать каждый тег (http://source.kentyde.com/fixlib/overview),, однако, я надеялся, что здесь будет возможен простой подход с использованием регулярных выражений, поскольку мне действительно нужна только пара тегов.

Есть ли в regex хороший способ извлечь нужные мне теги?

Ура, Victor

Ответы [ 3 ]

9 голосов
/ 18 января 2012

Нет необходимости разделять на "\ 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 здесь .

1 голос
/ 29 декабря 2011

^ A на самом деле \ x {01}, вот как он отображается в vim.В Perl я сделал это через разбиение по гексу 1, а затем разделение по "=", во втором разбиении значение [0] массива является тегом, а значение [1] является значением.

0 голосов
/ 21 ноября 2011

Используйте инструмент регулярных выражений, такой как expresso или regexbuddy.
Почему бы вам не разделить на ^A, а затем сопоставить ([^=])+=(.*) для каждого, помещающего их в хеш?Вы также можете отфильтровать с помощью переключателя, который по умолчанию не будет добавлять теги, которые вас не интересуют, и который имеет провал для всех тегов, которые вас интересуют.

...