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_ ];

しかし、これは何らかの理由で機能しません。これを行うと、常に false が返されます。

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

編集: ブースト バージョン 1.42 コンパイラ g++ 4.4 スピリット 0x2020

4

1 に答える 1

6

覚えておいてください: Spirit のパーサーは貪欲です。つまり、 を実行すると、が満たされなくなるqi::omit[ <something> ]まで文字が省略され続けます。は文字通り何でも<something>あるため(は任意の文字に一致するため、すべての文字に一致します)、残りの文字列全体を消費します。その後、「ChannelState:」に到達しなかったため、エラーが発生します。<something>char_*char_

あなたのやり方ではうまくいきません。*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); 

これは Boost 1.47 で動作することに注意してください。以前のバージョンでは失敗すると思います。

Boost バージョン 1.42 コンパイラ g++ 4.4 Spirit 0x2020

それらはかなり古いです。アップグレードを検討する必要があります。ブーストは現在1.47までです。

于 2011-11-04T18:53:42.860 に答える