2011-11-04 78 views
3

我想解析一個嘈雜的輸入,理想情況下,我將能夠看到一個節是否匹配的規則,如果它確實得到我需要的數據,並放棄其餘的。提升精神語法匹配嘈雜的輸入

我想要的數據如下。

Event: Newstate 
Channel: SIP/104-000001bb 
ChannelState: 6 
ChannelStateDesc: Up 

我想確保事件如果鍵入新狀態。

而且我需要通道狀態。其他人我不在乎(只是),所以我想忽略它,我希望它是靈活的,並接受任何重要的東西之間的廢話,我真的不想忽視這條線,而是忽略事件和通道狀態結束之間的任何事物,我捕獲該值。

到目前爲止我有:

typedef boost::fusion::vector2<std::string, std::string> vect; 
qi::rule<std::string::iterator, vect(), space> rule_ = 
      lit("Event: ")  >> *char_("a-zA-Z") >> 
      qi::omit[ *char_ ] >> 
      "ChannelState: " >> *char_("0-9") >> 
      qi::omit[ *char_ ]; 

,但是這是不工作由於某種原因,我總是假回來時,我這樣做:

vect v; 
bool r=qi::parse(it, str.end(), rule_, v); 

編輯:升壓版本1.42編譯g ++ 4.4精神0x2020

回答

6

記住:Spirit的解析器是貪婪的。這意味着如果您的電子郵件地址爲qi::omit[ <something> ],它將繼續忽略字符,直到不再滿足<something>。由於<something>實際上是任何東西char_匹配任何字符,所以*char_匹配所有字符),它會吃掉整個字符串的其餘部分。然後它會產生一個錯誤,因爲它從來沒有達到「ChannelState:」。

你這樣做的方式根本行不通。你必須有一些切斷開關來阻止*char_吃東西。

我不明白你爲什麼不把它們全部解析成std::map,而不是零碎地做。然後你可以挑選出你想要的元素。你說你不想要一些元素,所以只是忽略它們。

//Includes 
#include <boost/spirit/include/qi.hpp> 
#include <boost/fusion/adapted/std_pair.hpp> 

//Code 
using namespace boost::spirit; 
using ascii::char_; 
using ascii::string; 

qi::rule<std::string::iterator, std::pair<std::string, std::string>() > pair_rule = 
    *(char_ - ':') >> ':' >> 
    qi::omit[*ascii::space] >> 
    *(char_ - eol) >> (eol || eoi); 

qi::rule<std::string::iterator, std::map<std::string, std::string>() > map_rule = 
    +pair_rule; 

std::map<std::string, std::string> v; 
bool r = qi::parse(test.begin(), test.end(), map_rule, v); 

請注意,這個工程升壓1.47:

這將如下進行。我懷疑它會在早期版本上失敗。

升壓版本1.42編譯克++ 4.4精神0x2020

那些是相當陳舊。你應該考慮升級。 Boost現在高達1.47。

+0

感謝您的回覆,明天我回到工作崗位時,我必須給予回覆。我知道這些版本是舊的,但我必須確保它在當前的debian版本(squeeze)上編譯,它永遠在過去:( – 111111

+0

@ 111111:即使'std :: pair'和'std :: map'東西不適用於舊版本,你可以隨時更改屬性來存儲包含兩個'std :: string'的struct的'std :: vector'。 –

+0

是的,無論如何,看到至多會有超過15個元素,我會認爲std :: map的開銷會浪費。 – 111111