0

私は母の誕生日よりも早く正規表現を忘れてしまいます。それは主要なPITAです。とにかく、HTTP 応答ステータス行を解析するための RE が必要で、サブ要素を適切にキャプチャしました。私はこれを機能させました:

  const boost::regex status_line("HTTP/(\\d+?)\\.(\\d+?) (\\d+?) (.*)\r\n");
  std::string status_test1("HTTP/1.1 200 hassan ali\r\n");

  boost::smatch what;
  std::cout << regex_match(status_test1,what, status_line, boost::match_extra) << std::endl;
  std::cout << what.size() << std::endl;

  BOOST_FOREACH(std::string s, what)
  {
    std::cout << s << std::endl;
  }

4 番目のキャプチャ グループは、特に単語のトークン化について、私が大騒ぎしていたものです。しかし、私はそれを必要としないので、私の仕事は終わりました。ただし、「\ 0」で終わるスペースで区切られた文をトークン化する方法を知りたいと思います。これにより、削除された単語のベクトル/配列が得られます。

次のフラグメントを機能させることができません

  const boost::regex sentence_re("(.+?)( (.+?))*");
  boost::smatch sentence_what;
  std::string sentence("hassan ali syed ");

  std::cout << boost::regex_match(sentence,sentence_what,sentence_re, boost::match_extra) << std::endl;

  BOOST_FOREACH(std::string s, sentence_what)
  {
    std::cout << s << std::endl;
  }

一致するべきではありません"hassan ali syed "が、一致する必要が"hassan ali syed"あり、キャプチャグループはhassan ali syed(改行で)出力する必要がありますが、出力しますhassan syed syed(3番目のsyedのスペースに注意してください<space>syedキャプチャグループは再帰的なエンティティを処理できないと思いますか?

それで、PCRE構文でトークン化タスクを指定するためのクリーンな方法はありますか?それにより、クリーンなトークンベクトルが得られます(繰り返しなし-つまり、ネストされたグループが空白を取り除こうとしないでください)。

これが仕事に適したツールではないことはわかっています.spirit / lexxまたはboost::tokeniseが最適であり、それが正しい方法ではないこともわかっています. .net では、スクリーン スクレイピングを行うときに、トークンがなくなるまで正規表現を本文に繰り返し適用することで、テキストの本文にトークンを見つけます。

4

2 に答える 2

1

これは、Python regex で繰り返しサブパターンをキャプチャするという同様の質問を思い出させます。

スペースで区切られた単語の数がトークンの最大数に制限されている場合は、次のように、追加のサブパターン全体を追加できます。

"HTTP/(\\d+?)\\.(\\d+?) (\\d+?) ([^ ]+\s)?([^ ]+\s)?([^ ]+\s)?([^ ]+\s)?\n\r"

もちろん、これは恐ろしいことです。

ネストされたグループが必要な場合は、正規表現の実装で「繰り返しサブパターン」をサポートしないとこれを実行できないと思いregexます (リンクされた質問で使用されている Python の非標準モジュールを参照してください)。 functions - のローカル版string.split()

于 2012-03-27T15:21:04.760 に答える
0

Boostは、再帰的なグループ化を実行できる可能性がありますが、確かではありません。私はそれができないことに傾いています。
私はそれができる.NETしか知りません。

2つの部分で1つの正規表現を設計できます。最初の部分は特定のグループをキャプチャし、2番目の部分は1つのグループで残りすべてをキャプチャします。次に、キャプチャされた2番目の部分で別の再帰的な正規表現を実行できます。

このようなもの:
(specific)(part)(to)(capture)(all the remaining text)

次に、前の残りのテキストキャプチャに対してwhile(/(part)/)正規表現を実行します。

ブーストでそれを行う方法は次のとおりです-

const string status = "HTTP/1.1 200 hassan ali\r\n";

boost::regex rx_sentence ( "HTTP/(\\d+)\\.(\\d+)\\s+(\\d+)\\s*([^\\s]+(?:\\s+[^\\s]+)*)?.*" );
boost::regex rx_token ( "[^\\s]+" );

if ( boost::regex_match( status, what, rx_sentence) )
{
    std::cout << "\nMatched:\n-----------------\n" << "'" << what[0] << "'" << std::endl;

    std::cout << "\nStatus (match groups):\n-----------------" << std::endl;
    for (int i=1; i < 4; i++)
    {
        std::cout << i << " = '" << what[i] << "'" << std::endl;
    }
    std::cout << "\nTokens (search of group 4):\n-----------------" << std::endl;
    const string token_str = what[4];

    std::string::const_iterator start = token_str.begin();
    std::string::const_iterator end   = token_str.end();

    while ( boost::regex_search(start, end, what, rx_token) )
    {
        string token(what[0].first, what[0].second);
        cout << "'" << token << "'" << endl;
        start = what[0].second;
    }
}
else
    std::cout << "Didn't match" << std::endl;
于 2012-03-27T21:50:55.603 に答える