1

tr1::regex を使用して、文字列からいくつかの一致を抽出しようとしています。文字列の例は次のとおりです。

asdf werq "one two three" asdf

そして、私はそれから抜け出したいです:

asdf  
werq  
one two three  
asdf  

引用符で囲まれたものがグループ化されているので、正規表現を使用しようとしています\"(.+?)\"|([^\\s]+)。私が使用しているコードは次のとおりです。

cmatch res;
regex reg("\"(.+?)\"|([^\\s]+)", regex_constants::icase);
regex_search("asdf werq \"one two three\" asdf", res, reg);

cout << res.size() << endl;
for (unsigned int i = 0; i < res.size(); ++k) {
    cout << res[i] << endl;
}

しかし、それは出力します

3
asdf

asdf

私は何を間違っていますか?

4

2 に答える 2

0

あなたの正規表現エンジンは後読みアサーションをサポートしていないようです。後読みの使用を避けるには、次のことを試してください。

"([^"]*)"|(\S+)

または引用:

"\"([^\"]*)\"|(\\S+)"

この正規表現は機能しますが、各一致には 2 つのキャプチャがあり、そのうちの 1 つが空になります (引用符で囲まれていない単語の場合は 1 つ目、引用符で囲まれた文字列の場合は 2 つ目)。

これを使用できるようにするには、すべての一致を反復処理し、一致ごとに空でないキャプチャを使用する必要があります。

私は TR1 について十分に知らないので、すべてのマッチをどのように反復するか正確にはわかりません。しかし、私が間違っていなければ、res.size()は常に 3 になります。

たとえば、文字列asdf "one two three" werqの場合、最初の一致は次のようになります。

res[0] = "asdf"              // the entire match
res[1] = ""                  // the first capture
res[2] = "asdf"              // the second capture

2回目の試合は次のとおりです。

res[0] = "\"one two three\"" // the entire match including leading/trailing quotes
res[1] = "one two three"     // the first capture
res[2] = ""                  // the second capture

3 番目の一致は次のようになります。

res[0] = "werq"              // the entire match
res[1] = ""                  // the first capture
res[2] = "werq"              // the second capture

HTH。

于 2010-08-29T16:07:18.413 に答える
0

代わりに、次の正規表現を試してください。

(?<=")[^"]*(?=")|[^"\s]\S*

引用するときは、もちろんエスケープする必要があります。

"(?<=\")[^\"]*(?=\")|[^\"\\s]\\S*"

ところで、使用したコードは、match_any を使用していないため、ターゲット文字列の最初の単語のみに一致する可能性があります。結果で得られる 3 つの項目は、おそらく (1) 一致全体、(2) 空の最初のキャプチャ、および (3) 一致のソースである 2 番目のキャプチャです。

于 2010-08-29T04:39:48.270 に答える