さて、前回までの記事で、クラスを使用すると既存のコードに手を入れずに機能追加しやすいことを見てきました。

その続きです。

ここでは、ワイルドカードにマッチした文字列を取得してみましょう
!!

 ただし、最短マッチすることにご注意ください。
 例えば"a*b*c"で検索をかける場合、対象文字列が"a1b1b1c"の場合、2パターンのマッチの
 仕方があるのが分かるかと思います。
  マッチ①: a(1)b(1b1)c
  マッチ②: a(1b1)b(1)c
 最短マッチとはマッチ①のように一番短くなるような検索を指します。


前置きはともかくとして、
ここでやっと今まで触れてこなかったコールバックのクラスが登場します。
こうご期待!!




【サンプル】
前回の記事のmain関数ごと以下のコードで置き換えてください。



#include <map>

/**
<pre>
*や?にマッチした文字列を溜め込むコールバッククラス。
マッチした文字は、this->resultMap()関数がmapとして返却する。
 ・mapのキー ⇒ ワイルド検索クラス(WildSearch)に設定した番号num。
 ・mapの値  ⇒ マッチした文字。
※番号numは、パース関数などを参照。
</pre>
*/
class StockMatchCallback : public MatchCallback{
public:
///
virtual void send(const int num, const char* pos, const int len){
m_stockMap[num] = string(pos, len);
};
///
map<int, string>& resultMap() { return m_stockMap; };
private:
map<int, string> m_stockMap;
};


//------------------------------------
int main(int argc, char *argv[]) {
MCharVector excludeVec;
StockMatchCallback callback;

//パース
WildSearchAPtr retAPtr = parsePartialWildCard("ab*c*d", getCharSet("sjis"));
scoped_ptr<WildSearch> pattern(retAPtr.release());

cout << "ワイルドカード部分の取得" << endl;

//テスト
const char* str = "11ab123c1d11";
SearchPointer p(str, getCharSet("sjis"), &callback);
pattern->search(p);

//
cout << "search for " << str << endl;
cout << "1st match string is: " << callback.resultMap()[1] << endl;
cout << "2nd match string is: " << callback.resultMap()[2] << endl;

system("PAUSE");
return EXIT_SUCCESS;
};




【出力】
ワイルドカード部分の取得
search for 11ab123c1d11
1st match string is: 123
2nd match string is: 1
続行するには何かキーを押してください . . .



【説明】
ワイルドカードで一致した部分を取得するなんて!どんだけ大変なんだ~!

って思いませんでした?

なんと、ここまで来るとクラス1つ追加するだけです!ビックリマーク
こうご期待などと書いておきながら、5ステップ程度のクラスですビックリマーク


単純にWildSearchクラスから通知された位置をmapクラスに登録するだけです。

何度も書きますが、クラスを使用するとこのように機能拡張に幅が出るのです!!
さすがクラス!!C++!!

ちなみに、上記の例ではparsePartialWildCard()という部分一致の関数でパースしました。
以前出てきた完全一致のparseWildCard()という関数も使用できます。

ほんの少しでもクラスを使う面白さが伝わっているとうれしいです!


【拡張について】
さて、このコールバックについてもいろいろ拡張できます。
例えば、デバッグ用に標準出力するコールバックを作るとか、
検索しながら、ワイルドカードが見つかるたびに何か他のことをするコールバックとか。

また、複数のコールバックを保持して呼び出すコールバックを作れば、
いくつでもコールバックを呼び出すことができます。
実行時に呼び出すコールバックを変えるだけで処理を変更でき、便利ですよね。




【その他の関連記事】
このワイルド検索の記事はシリーズになっていて、順を追ってみてもらえればと思います。

 ・ワイルドカード検索をする
 ・WildSearchを"ac*c"などの文字列から自動で作成する
 ・部分一致のワイルドカード検索をする
 ・*や?にマッチした文字列をコールバックを使用して取得する
 ・Antパスマッチを実装する
 ・おまけ:ワイルドカード検索すべてのコードをまとめたもの