2017-02-11 5 views
3

私はパターン「"XYZ \ D \ D」と、このパターンが何回も発生する可能性があります『大きめ』の文字列を持っている。は、正規表現の検索を実行するとstdに交換してください::文字列

私の目的は、見つけることです。パターンのすべてのインスタンス文字列にし、元の文字列に「」文字でその試合ですべての文字を置換する

は、私がこれまで持っているが、エラーがあります以下:

#include <iostream> 
#include <regex> 

int main() { 
    std::regex exp("XYZ\\d\\d"); 
    std::smatch res; 
    std::string str = " XYZ111 d-dxxxxxxx XYZ222 t-nyyyyyyyyy XYZ333 t-r "; 

    auto itr = str.cbegin(); 

    while (std::regex_search(itr, str.cend(), res, exp)) { 

     std::cout << "[" << res[0] << "]" << std::endl; 

     for (auto j = res[0].first; j != res[0].second; ++j) { 
      *j = 'A'; // Error as dereferencing j causes a const reference 
     } 

     itr += res.position() + res.length(); 
    } 

    std::cout << std::endl; 

    std::cout << "mod: " << str << std::endl; 

    return 0; 
} 

C++を使用しているときに正しいプロセスがわからない11 regex私の仕事を達成するための設備。

も思っていた1が、彼らはすべての試合が発生した上で試合を変更したいのですがどのように指定することができ数子を取るregex_replaceののようなものはありますか?

+0

「XYZ」を検索して2桁の数字が続くかどうかを確認するのに約3行のコードしかかかりません。このような単純なマッチのために、正規表現を使用するのは残酷なようです。 –

答えて

3

グローバルな正規表現ベースの置換が必要です。 Here're明示的なループせずにこれを行うには3つの方法は、(必ずそこにいる "暗黙の" 正規表現でループコードを置き換え):

#include <iostream> 
#include <string> 
#include <regex> // std::regex 
#include <pcrecpp.h> // pcrecpp::RE -- needs "-lpcrecpp -lpcre" 
#include <pcrscpp.h> // pcrscpp::replace -- needs "-lpcrscpp -lpcre" 

int main() { 
    std::regex std_rx (R"del(XYZ\d\d)del"); 
    pcrecpp::RE pcrecpp_rx (R"del(XYZ\d\d)del"); 
    pcrscpp::replace pcrscpp_rs(R"del(s/XYZ\d\d/A/g)del"); 
    std::string str = " XYZ111 d-dxxxxxxx XYZ222 t-nyyyyyyyyy XYZ333 t-r "; 

    std::cout << "std::regex way: " << std::regex_replace (str, std_rx, "A") << std::endl 
       << "pcrecpp way: "; 

    std::string buffer(str); 
    pcrecpp_rx.GlobalReplace("A", &buffer); 

    std::cout << buffer << std::endl 
       << "pcrscpp way: "; 

    pcrscpp_rs.replace_store(str); 
    std::cout << pcrscpp_rs.replace_result << std::endl; 

    return 0; 
} 

結果:

std::regex way: A1 d-dxxxxxxx A2 t-nyyyyyyyyy A3 t-r 
pcrecpp way: A1 d-dxxxxxxx A2 t-nyyyyyyyyy A3 t-r 
pcrscpp way: A1 d-dxxxxxxx A2 t-nyyyyyyyyy A3 t-r 

std::regexニーズC++ 11個の機能(this answerを参照してください)、単純なパターンではPCREよりも約2倍遅くなりますが、C++ 11コンパイラを使用している限り、複雑なものでは悪化すると予想されますが、追加のライブラリは必要ありません。 PCRECPPは、Googleによって書かれたPCRE C++ラッパーです。 PCRSCPPは、Perlのような正規表現ベースの置換機能を提供するPCREのラッパーです。したがって、この範囲ではPCRECPPよりはるかに機能が豊富です。

4

置き換えを行うために使用できる位置と長さがあるため、エラーを取り除きたい場合はstd::match_resultsをnon-constイテレータでインスタンス化できます(すべてのstdlibのデフォルトインスタンシエーションはconstを使用します) 。

#include <iostream> 
#include <regex> 

int main() { 
    using strmatch = std::match_results<std::string::iterator>; 

    std::regex expr("XYZ\\d\\d"); 
    strmatch res; 
    std::string str = " XYZ111 d-dxxxxxxx XYZ222 t-nyyyyyyyyy XYZ333 t-r "; 

    auto itr = str.begin(); 

    while (std::regex_search(itr, str.end(), res, expr)) { 

     std::cout << "[" << res[0] << "]" << std::endl; 

     for (auto j = res[0].first; j != res[0].second; ++j) { 
      *j = 'A'; // Error as dereferencing j causes a const reference 
     } 

     itr += res.position() + res.length(); 
    } 

    std::cout << std::endl; 

    std::cout << "mod: " << str << std::endl; 

    return 0; 
} 
関連する問題