2011年11月25日金曜日

re2のxxxNの使い方

re2はGoogleが公開しているC++用の正規表現ライブラリです。速度も速い(らしい)し、ちゃんと日本語一文字も"."でマッチしてくれるので、社内でも好んで使われています。

たくさん機能があるようなんですが、Web上であまり情報がなかったり、詳細はheaderファイル見てね!みたいなことが書かれていて、なかなかマスターするのが難しいライブラリです。特に、マッチ箇所(いわゆるgroup)が複数あるときにどうすればいいのかすぐにわかりません。私も以前ここではまって、色々調べてどうにか動いたことがありました。ちょうど@chezouさんが困っていたようなので、メモのつもりで晒してみましょう。



説明するより、コード読むがはやし、ということでサンプルを!

  1. #include <re2/re2.h>  
  2. #include <string>  
  3. #include <vector>  
  4. #include <iostream>  
  5.   
  6. using namespace std;  
  7.   
  8. int main() {  
  9.   string pat = "(.)(.)(.)(.)";  
  10.   string text = "hoge";  
  11.                                                                                                                                                                            
  12.   re2::RE2 re(pat);  
  13.   re2::StringPiece input(text);  
  14.   int groupSize = re.NumberOfCapturingGroups();  
  15.   vector<re2::RE2::Arg> argv(groupSize);  
  16.   vector<re2::RE2::Arg*> args(groupSize);  
  17.   vector<re2::StringPiece> ws(groupSize);  
  18.   for (int i = 0; i < groupSize; ++i) {  
  19.     args[i] = &argv[i];  
  20.     argv[i] = &ws[i];  
  21.   }  
  22.   re2::RE2::PartialMatchN(input, re, &(args[0]), groupSize);  
  23.   for (int i = 0; i < groupSize; ++i)  
  24.     cout << ws[i] << endl;  
  25. }  

基本的にxxxN関数を使えばOKのようです。まず、RE2オブジェクトのgroupの数はNumberOfCaptureingGroupsで取れます。xxxN関数には、書き込み先のArgへのポインタの配列を渡す必要があります。なので、Argポインタのvector(これを関数に渡す)と、Arg実態のvectorを作ります。実態の方には、それが書き込む先のStringPieceへのポインタを代入しておくといいようです。ここは、intポインタなどを代入すれば、intに変換されて代入されるでしょう。この辺は、なんとなく書いたのでもっと良い書き方があるのかもしれません。これでマッチさせれば、最終的にStringPieceのvectorに結果が代入されました。

0 件のコメント:

コメントを投稿