5

正規表現を使用して入力文字列を解析しようとしています。繰り返しグループをキャプチャしようとすると問題が発生します。私は常にグループの最後のインスタンスに一致しているようです。Reluctant (欲張りではない) 量指定子を使ってみましたが、何か足りないようです。誰か助けてくれませんか?

試した正規表現:

(OS)\\s((\\w{3})(([A-Za-z0-9]{2})|(\\w{3})(\\w{3}))\\/{0,1}){1,5}?\\r

(OS)\\s((\\w{3}?)(([A-Za-z0-9]{2}?)|(\\w{3}?)(\\w{3}?))\\/{0,1}?){1,5}?\\r

入力文字列:

OS BENKL/LHRBA/MANQFL\r\n

私は常に MANQFL group である最後のグループを取得しているようです。(MAN QFL)私の目的は、3 つのグループすべてを取得することです (1 ~ 5 つのグループが存在する可能性があります)。

(BEN KL) , (LHR BA) and (MAN QFL). 

C++ コード スニペット:

std::string::const_iterator start = str.begin(), end = str.end(); 
while(regex_search(start,end,what,expr)) 
{ 
  cout << what[0]; 
  cout << what[1]; 
  ... 
  start += what.position () + what.length (); 
}

このループは 1 回だけ実行されますが、この例では 3 回実行されると予想しています。どんな助けでも大歓迎です。

4

4 に答える 4

4

boost::regex から複数の一致を取得する最良の方法は、regex_iterators を使用することです。この例は、あなたが望むことをするはずです。

#include <iostream>
#include <string>
#include <boost/regex.hpp>

int main() {
    std::string a = "OS BENKL/LHRBA/MANQFL\r\n";
    const boost::regex re("[A-Z]{3}[A-Z]*");
    boost::sregex_iterator res(a.begin(),a.end(),re);
    boost::sregex_iterator end;
    for (; res != end; ++res)
        std::cout << (*res)[0] << std::endl;
}
于 2011-06-14T23:09:21.040 に答える
1

キャプチャグループのすべての反復を提供できることがわかっている唯一の正規表現フレーバーは、.NET正規表現フレーバーです。通常、正規表現エンジンは、各キャプチャグループの最後の反復のみを保存します。

この種の問題の一般的な解決策は、1つの正規表現を使用してグループのすべての反復をキャプチャし、2番目の正規表現を使用して最初の正規表現の結果を個別の項目に分割することです。アランは、この特定の状況でこれを行う方法をすでに説明しました。

于 2010-07-12T08:05:54.357 に答える
0

これは予想される動作です。キャプチャ グループが量指定子によって制御されている場合、繰り返しのたびに、前回キャプチャされたものはすべて上書きされます。すべての一致を取得する最も簡単な方法は、次のようにキャプチャ グループを全体に配置することです。

(OS)\\s(((\\w{3})(([A-Za-z0-9]{2})|(\\w{3})(\\w{3}))\\/?){1,5})\\r

そのグループにはBENKL/LHRBA/MANQFL、 で分割できる が含まれることになり/ます。

于 2010-06-28T17:55:26.973 に答える
0

ここで繰り返しキャプチャに関するセクションを読んでください: http://www.boost.org/doc/libs/1_47_0/libs/regex/doc/html/boost_regex/captures.html

基本的に、必要なのは、適切な #defines とフラグを regex_search 呼び出しに渡すことで有効にできる実験的な機能です。

于 2011-08-05T17:58:42.980 に答える