宿題をひとつ解きますた。
/$pattern/g
に相当する記述方法はないか?
boost::regex_grep()
[LINK] というのはあったらしいが、すでに deprecated 。Predicate
とかいうコールバックらしきものの設定が必須な模様で、そういう意味でも使いにくい (Perl の grep
関数を意識してるのかな?)。boost::regex
コンストラクタで std::regex_constants::grep
または std::regex_constants::egrep
を指定した場合、どうなるか?tr/.../.../
相当の記述法も併せて検証する。ふつーに iterator 回せって? まぁそうなんだけどね。boost::regex_iterator
[LINK] を boost::make_regex_iterator()
を用いて生成する方法と、でいけそうです (訂正: Tue Jun 5 22:22:23 JST 2007)。以下、サンプル。boost::basic_regex
のコンストラクタに渡すパラメータ値 boost::regex_constants::egrep
との併用
#include <iostream> #include <string> #include <boost/regex.hpp> using namespace std; using boost::regex; using boost::smatch; using boost::sregex_iterator; using boost::regex_constants::egrep; using boost::make_regex_iterator; int main() { string text = "foo bar (baz) hoge (huga) o(yoy)o nan(to iu ko)toda-"; for (sregex_iterator it = make_regex_iterator(text, regex("\\(([^\\)]+)\\)", egrep)); it != sregex_iterator(); it++) { cout << (*it)[1] << endl; } }
実行結果はこんな感じ。
C:\Program_1\vs8\regex_test_mb\debug>regex_test_mb.exe baz huga yoy to iu ko C:\Program_1\vs8\regex_test_mb\debug>
boost::regex_constants::egrep
は不要でした。
それから、一括置換を行いたい場合は、普通に boost::regex_replace()
アルゴリズムを使えばいい模様です (逆に一括では置換したくない場合はどうすればいいんだ?)。boost::match_results::format()
はあくまでマッチ結果を利用して Perl 風に置換のフォーマットを記述できるというただそれだけの代物のようです。
以下、総括的なサンプルソース。
#include <iostream> #include <string> #include <boost/regex.hpp> using namespace std; using boost::regex; using boost::sregex_iterator; using boost::make_regex_iterator; using boost::regex_replace; int main() { string text = "foo bar (baz) hoge (huga) o(yoy)o nan(to iu ko)toda-"; cout << text << endl; for (sregex_iterator it = make_regex_iterator(text, regex("\\(([^\\)]+)\\)")); it != sregex_iterator(); it++) { cout << (*it)[1] << endl; cout << it->format("[$1]") << endl; } cout << regex_replace(text, regex("\\(([^\\)]+)\\)"), "[$1]") << endl; }
実行結果は以下のとおり。
C:\Program_1\vs8\regex_test_mb\debug>regex_test_mb.exe foo bar (baz) hoge (huga) o(yoy)o nan(to iu ko)toda- baz [baz] huga [huga] yoy [yoy] to iu ko [to iu ko] foo bar [baz] hoge [huga] o[yoy]o nan[to iu ko]toda- C:\Program_1\vs8\regex_test_mb\debug>
s/〜/eg みたいなことをやる方法もわかったので追記。よーするに regex_replace()
アルゴリズムを自前でやっつける方法ですね。
その前に。まず、make_regex_iterator()
は、regex_iterator
のコンストラクタを呼べるのであれば、不要です。ていうか、効率を考えればむしろそうするべきです。make_regex_iterator()
自体は regex_iterator
コンストラクタの単なる構文糖に過ぎません。
で、自前でテキスト置換を実装するにはマッチしなかった部分のフレーズが (適切なタイミングで) 得られる必要がありますが、それは match_results::prefix()
で取得できます。また、マッチングのループで舐められることのなかった部分 (最後にマッチしたフレーズよりも後ろの部分) については、最後に評価された regex_iterator
の match_results::suffix()
にて取得できます。
セコメントをする