19

文字列内の特定のパターンを別の置換パターンに置き換えようとしています。

例:

string test = "test replacing \"these characters\"";

私がやりたいことは、すべての ' ' を '_' に置き換え、その他の文字または数字以外のすべての文字を空の文字列に置き換えることです。次の正規表現を作成しましたが、正しくトークン化されているようですが、(可能であれば) を使用して条件付き置換を実行する方法がわかりませんregex_replace

string test = "test replacing \"these characters\"";
regex reg("(\\s+)|(\\W+)");

置換後の期待される結果は次のようになります。

string result = "test_replacing_these_characters";

編集: ブーストを使用できないため、タグから除外しました。したがって、ブーストを含む回答はご遠慮ください。これを標準ライブラリで行う必要があります。別の正規表現が目標を達成するか、2回のパスで立ち往生している可能性があります。

EDIT2:元の正規表現の時点でどの文字が含まれていたか覚えていませんでし\wた。調べた後、式をさらに単純化しました。ここでも、\s+ に一致するものはすべて「_」に置き換え、\W+ に一致するものは空の文字列に置き換えることを目標としています。

4

2 に答える 2

27

c++ (0x, 11, tr1) の正規表現は、すべての場合に実際に機能するとは限りません (stackoverflow) ( gcc についてはこのページで正規表現というフレーズを調べてください) 。

コンパイラが必要な正規表現をサポートしているかどうかを試してください。

#include <string>
#include <iostream>
#include <regex>

using namespace std;

int main(int argc, char * argv[]) {
    string test = "test replacing \"these characters\"";
    regex reg("[^\\w]+");
    test = regex_replace(test, reg, "_");
    cout << test << endl;
}

上記は Visual Studio 2012Rc で動作します。

編集 1 : 1 つのパスで (一致に応じて) 2 つの異なる文字列に置き換えるには、ここでは機能しないと思います。/ePerl では、これは評価された置換式 ( switch )内で簡単に実行できます。

したがって、既に推測したように、2 つのパスが必要になります。

 ...
 string test = "test replacing \"these characters\"";
 test = regex_replace(test, regex("\\s+"), "_");
 test = regex_replace(test, regex("\\W+"), "");
 ...

編集2

でコールバック関数 tr()を使用できる場合regex_replaceは、次のように置換を変更できます。

 string output = regex_replace(test, regex("\\s+|\\W+"), tr);

tr()交換作業を行うと:

 string tr(const smatch &m) { return m[0].str()[0] == ' ' ? "_" : ""; }

問題は解決したでしょう。残念ながら、一部の C++11 正規表現実装にはそのようなオーバーロードはありませんが、Boostには 1 つがあります。以下はブーストで動作し、1 つのパスを使用します。

...
#include <boost/regex.hpp>
using namespace boost;
...
string tr(const smatch &m) { return m[0].str()[0] == ' ' ? "_" : ""; }
...

string test = "test replacing \"these characters\"";
test = regex_replace(test, regex("\\s+|\\W+"), tr);   // <= works in Boost
...

いつの日か、これは C++ 11または次に来る番号で動作するようになるでしょう。

よろしく

rbo

于 2012-07-16T17:15:25.463 に答える