Gobble up pudding

プログラミングの記事がメインのブログです。

MENU

C++11が便利すぎる 正規表現 ~regex編~

スポンサードリンク

f:id:fa11enprince:20200629103050j:plain
C++11になってから複雑怪奇さをより増した一方で、
実はめちゃくちゃ使いやすく便利になっていることに最近気づき始めました。
ここで紹介するコードはC++11に対応しているものでないと実行できません。
Visual Studioだと2013以降です。
g++だと -std=c++11 オプションを付けてあげればOKです。
サンプルコードは文字列の一覧からWindows 8.1を引き当ててやるものです。
他言語で正規表現を使ったことのある人は理解がスムーズかと思います。
C++でも色んなパターンがある中からWindows 8.1をとりたいよーというマジキチなことをしたいということがあることがまれにあります。
strstr()とかじゃどうしよーもねーよーとかめんどくさすぎるとか。
いままでそんな要望あったら他言語使って回避とかいろいろね、もうね……。
もしくはBoost入れるとかそんなことになるでしょう。
もしくは…
f:id:fa11enprince:20140417225835g:plain
なんてことには絶対ならないですが……。
それが標準ライブラリに取り込まれるなんて感動です。

正規表現サンプルコード

実行結果

5個目の [Windows8.1] がマッチしました
6個目の [MicrosoftWindows8.1] がマッチしました
7個目の [Windows 8.1] がマッチしました
8個目の [Windows 8.1 Update 1] がマッチしました
9個目の [MicrosoftWindows8.1Update1] がマッチしました
10個目の [Microsoft Windows 8.1 Update 1] がマッチしました
11個目の [microsoft windows 8.1 update 1] がマッチしました

簡単な解説

まず、std::vector testの初期化の部分ですが、
配列と同じように初期化できます。涙がでるくらい楽です。
ちなみに=(イコール)はなくてもOKです。

いままでは、一旦配列にいれてvector::push_back()で順次突っ込んでやるとかそんな方法程度しかありませんでした(もうちょいうまい方法もある)。
std::regexでパターンを指定します。ここで使っている正規表現の記法はECMAScript準拠の一般的なものです。
ここのサイトが詳しいです。
ECMAScript syntax - C++ Reference

\記号は\\としてエスケープしてやらなきゃならないのはやっぱりC/C++/Java同様です。
結果を取りたい場合はstd::smatchというのを使います。
C#のmatch.Groupsみたいな使い勝手です(インデックス1以降がカッコで括ったグループが順に取れるアレです)。
英語ですがサンプルコードがついていてわかりやすいここを参考にしました。
http://www.cplusplus.com/reference/regex/
cpulusplus.comさんは偉大だ。
vectorもstringもだんだん使いやすくなっていってますね。

最後に補足ですが、forループにあるautoキーワードもC++11からです。
それまでCから引き続いて存在しているあんまり知られていないautoキーワードとは別物です。auto int = 10;とかいうやつね。要は普通の変数宣言の時に使う省略可能なキーワードautoではなくて、この場合は型推論のautoで見りゃ何かわかるだろっていうのを勝手にやってくれるものです。今回の場合は
for (std::vector::iterator it = test.begin(); it != test.end(); ++it)
としなきゃいけないのをautoで済ませることができています。