2011-11-21 19 views
6

FIX protokol iletilerini içeren bir günlük dosyalarını ayrıştırmam gerekiyor.Regex'te FIX protokolünü ayrıştırma?

Her satırda başlık bilgileri (zaman damgası, günlüğe kaydetme düzeyi, bitiş noktası) ve ardından bir FIX yükü bulunur.

Başlık bilgisini adlandırılmış gruplara ayrıştırmak için düzenli ifadeler kullanıyorum. Ör:

<?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* 
Sonra FIX yük kendisi gelip

mesela (^ A Her etiketi arasındaki ayırıcı ise): Bu (örneğin "A" dan gelen özel etiketleri ayıklamak gerekir

8=FIX.4.2^A9=61^A35=A...^A11=blahblah... 

35 = veya "blahblah" dan 11 =) ve diğer tüm maddeleri görmezden gelmeliyiz - temelde "35 = A" ve daha sonra "11 = blahblah" a kadar olan herhangi bir şeyi görmezden gelmem gerek, sonra da bundan sonra hiçbir şeyi görmezden gelmeliyim.

Her bir etiketi ayrıştırabilecek bir kitaplık var (http://source.kentyde.com/fixlib/overv iew), ancak, mümkünse burada regex kullanarak basit bir yaklaşımı umuyordum, çünkü sadece birkaç etikete ihtiyacım var.

İhtiyaç duyduğum etiketleri ayıklamak için iyi bir yol var mı?

Alkış, Victor

cevap

0

espresso veya RegexBuddy gibi regex aracı kullanın.
Niçin ^A'a bölünmüyor ve her biri bir karmaşaya koyarak ([^=])+=(.*) eşleşmiyor? İlgilendiğiniz etiketleri ilginizi çekmeyecek ve ilgilendiğiniz tüm etiketler için bir düşüşe sahip olmayacak bir anahtarla da filtreleyebilirsiniz.

1

^A aslında \ x {01}, Vim'de nasıl göründüğü. Perl'de bunu hex 1'de bir split ile yaptım ve daha sonra "split" in ikinci bölünmesinde, dizinin [0] değeri Tag ve value [1] Value'dır.

9

"\ x01" 'e bölünmeye gerek yok, ardından regex ve filtrelemeye gerek yok. Eğer sadece etiketi istedi Eğer 34,49 ve 56 (MsgSeqNum, SenderCompId ve TargetCompId) Eğer regex olabilir: Eğer gönderen bir hata neden olabilir verileri gömülü sahip değil biliyorsanız böyle

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

Basit regexes çalışacak herhangi bir basit ifade. Özellikle:

  1. Yok Ham Veri alanları (aslında verilerin kombinasyonu len ve RawDataLength, rawData (95/96) ya da XmlDataLen, XMLData gibi ham verileri (EncodedTextLen, EncodedText gibi Unicode dizeleri 212213)
  2. yok kodlanmış alanlar (354/355)

bu davaları işlemek için ek ayrıştırma çok zaman alır. özel bir piton ayrıştırıcı ama kullanmak bile yukarıda referans fixlib kodu yanlış bu davaları alır. ama veri bu istisnaların açık olup olmadığını Yukarıdaki regex, istediğiniz alanların güzel bir dict döndürmelidir.

Düzenleme: Yukarıdaki regex'i olduğu gibi bıraktım ancak son eşleşme öğesinin (?=\x01) olması için gözden geçirilmesi gerekiyor. Açıklama, @ tropleee'nin answer here adresinde bulunabilir.

+2

Bu kabul edilenlerden daha iyi bir yanıttır. Kesinlikle "len" alanlarını hesaba katmanız gerekiyor. Herkes bunları her zaman unutur! Ayrıca, FIX mesajları yeni satır karakterleri içerebilir (yani, etiket 58'de), dolayısıyla emin olmak için re.DOTALL'ı kullanmanız gerekir. – noahlz

+2

[Bu soru] 'da açıklandığı gibi (http://stackoverflow.com/questions/31198950/parsing-fix-message-in-regex/31199578#31199575), bu çözümde bir hata vardır - iki eşleşme olduğunda başarısız olur bitişik. – tripleee

İlgili konular