web-dev-qa-db-ja.com

文字列の正規表現一致を条件付きで置換する

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

例:

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 +に一致するものはすべて空の文字列に置き換える必要があります。

16
pstrjds

C++(0x、11、tr1)正規表現 実際には機能しない(stackoverflow) すべての場合(- phrase regex on このページ for 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で動作します。

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

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

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

編集2

_regex_replace_でcallback functiontr()を使用できる場合は、次のように置換を変更できます。

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

tr()で置換作業を行います:

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

問題は解決されたでしょう。残念ながら、一部のC++ 11正規表現実装ではno such overloadがありますが、Boost has oneがあります。以下は、ブーストで機能し、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

25
rubber boots