すみません。
ワイルドカード検索の記事をシリーズで読んでいただいた方は、
「コードをコピーするのが面倒」って思いましたよね。きっと汗

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

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


【すべてをまとめたコード】
そこで、ここではシリーズ全てのコードを載せます。
これで一回コピーすれば遊べると思います。

記事の順番にコードを記述しましたので、だんだんコードが増えて行くのが分かるかと思います。

先立って、以下のコードをコピーして作っておいてください。
 ・code.hpp、code.cppファイル
 ・MCharIterator.hpp、MCharIterator.cppファイル


//---------------------------------------------------
//---------------------------------------------------
// ****記事**** ワイルドカード検索をするには?
//---------------------------------------------------
//---------------------------------------------------

#include <iostream>
#include <string>
#include <vector>
#include <iostream>
#include <sstream>


#include <boost/utility.hpp>
#include <boost/scoped_ptr.hpp>


#include "code.hpp"


namespace nana{


//検索コールバッククラス------------------------------------------------

///や?にマッチした時にコールバックされる基底クラス。
class MatchCallback{
public:
virtual ~MatchCallback(){};
///
virtual void send(const int num, const char* pos, const int len){};
};


/**
<pre>
検索対象文字の開始位置と、現在の位置、終端位置を保持するホルダークラス。
また、何か見つかったときに報告ができるコールバッククラスも保持する。
</pre>
*/
struct SearchPointer{
public:
/**
コンストラクタ
@param str [in]検査対象文字列
@param charSet [in]文字コード
@param callback [in]コールバック (deleteは各自で行うこと)
*/
SearchPointer(const char* str, const CharSet* pcharSet, MatchCallback* pcallback =NULL)
: startPos(str), curPos(str), endPos(str + strlen(str))
, callback(pcallback), charSet(pcharSet)
{
if(callback == NULL) this->callback=&dummyMatchCallback;
};

///マッチした時のコールバック
MatchCallback* callback;
///現在の位置
const char* curPos;
///開始位置
const char* const startPos;
///終端位置
const char* const endPos;
///文字コード
const CharSet* const charSet;
///コールバックがNULLのときに代入する
static MatchCallback dummyMatchCallback;
};

///文字の配列
typedef vector<FixedMChar> MCharVector;


//-------------------------------------------------
//ワイルド検索クラス
//-------------------------------------------------
namespace wild{

///配列内に存在するか?
inline const bool exists(const MCharVector& vec, const MChar& mchar){
if(vec.empty()) return false;
return find(vec.begin(), vec.end(), mchar) != vec. end();
};


/**
<pre>
ワイルドカードの検索基底クラス。
</pre>
@note 代入は不可
*/
class WildSearch : noncopyable{
public:
WildSearch(const int& num, const WildSearch* next, const int& kind)
: m_num(num), m_pwildSearch(next), m_kind(kind) {};
virtual ~WildSearch(){};

///検索する。見つかった場合true。
virtual const bool search(SearchPointer& p) const =0;
const WildSearch& next() const { return *m_pwildSearch; };
const int& num() const { return m_num; };
const int& kind() const { return m_kind; };

protected:
///検索と通知(検索に成功すると通知する)
const bool nextSearchAndSend(SearchPointer& p, const char* start, const char* cur, const int size) const{
p.curPos = start;
if(!this->next().search(p)) return false;
p.callback->send(this->num(), cur, size);
return true;
};

private:
///次の検索
scoped_ptr<const WildSearch> m_pwildSearch;
///ワイルドの番号
const int m_num;
///検索種別
const int m_kind;
};


///文字列の終端を検索するクラス。
class TerminatorSearch : public WildSearch{
public:
enum{NUM=-2, KIND=5};

TerminatorSearch()
: WildSearch(NUM, NULL, KIND) {};

///
virtual const bool search(SearchPointer& p) const{
//終了位置ならtrue
if(p.curPos >= p.endPos){
p.callback->send(this->num(), p.curPos, 0);
return true;
}
return false;
};
};


///アスタリスクの検索クラス
class AstaSearch : public WildSearch{
public:
enum{KIND=1};

///
AstaSearch(const int& num, const WildSearch* next, const MCharVector& exclude)
: m_exclude(exclude), WildSearch(num, next, KIND) {};

///
virtual const bool search(SearchPointer& p) const{
const char* cur = p.curPos;
const char* calcEndPos = p.endPos;

//検索開始
MChar i(p.curPos, p.charSet);
for(; i.pos() < calcEndPos; ++i){
//除外される文字だった場合
if(exists(m_exclude, i)){
return this->nextSearchAndSend(p, i.pos(), cur, i.pos() - cur);
}

//現在の位置から次の検索を行う
if(this->nextSearchAndSend(p, i.pos(), cur, i.pos() - cur)){
return true;
}
}

return false;
};

private:
const MCharVector m_exclude;
};


///?の検索クラス
class QuestionSearch : public WildSearch{
public:
enum{KIND=2};

//
QuestionSearch(const int num, const WildSearch* next, const MCharVector& exclude)
: m_exclude(exclude), WildSearch(num, next, KIND) {};

virtual ~QuestionSearch(){}

//
const bool search(SearchPointer& p) const{
const char* cur = p.curPos;
MChar m(cur, p.charSet);
const char* next_pos = cur+m.size();
if(next_pos > p.endPos) return false;

//除外される文字だった場合
if(exists(m_exclude, m)){
return false;
}

//次の文字以降が一致するか?
return this->nextSearchAndSend(p, next_pos, cur, m.size());
};

private:
const MCharVector m_exclude;
};


///固定文字列の検索クラス
class OnlyStrSearch : public WildSearch{
public:
enum{NUM=-3, KIND=3};

OnlyStrSearch(const int num, const string& str, const WildSearch* next)
: m_str(str), WildSearch(num, next, KIND) { };

///
const bool search(SearchPointer& p) const{
const char* cur = p.curPos;
if(cur > p.endPos - m_str.size()) return false;

//文字列が一致するか?
if(strncmp(p.curPos, m_str.data(), m_str.size()) ==0){
//次の検索を行う
return this->nextSearchAndSend(p, cur + m_str.size(), cur, m_str.size());
}

return false;
};

private:
const string m_str;
};


}; //namespace wild{
}; //namesapce nana{


//使用サンプルコード開始-------------------------------------

using namespace nana::wild;
using namespace nana;

///static変数の初期化
MatchCallback nana::SearchPointer::dummyMatchCallback;

//ワイルド検索
void search(const scoped_ptr<WildSearch>& pattern, const char* str){
SearchPointer p(str, getCharSet("sjis"));
cout << "pattern: " << str << ", ";
if(pattern->search(p)){
cout << "true" << endl;
}else{
cout << "false" << endl;
}
}


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


//"ab*c"
scoped_ptr<WildSearch> pattern(
new OnlyStrSearch(-3, string("ab"), //ab
new AstaSearch(1, //*
new OnlyStrSearch(-3, string("c"), new TerminatorSearch()) //c
,excludeVec
)
)
);

//テスト
search(pattern, "abc");
search(pattern, "abdddc");
search(pattern, "ac");
search(pattern, "abcd");

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















//---------------------------------------------------
//---------------------------------------------------
// ****記事**** ワイルドカード文字列をパースするには?
//---------------------------------------------------
//---------------------------------------------------
//パース----------------------------------------------
typedef auto_ptr<WildSearch> WildSearchAPtr;


//ワイルドカード文字を作る
const MCharVector createMCharVectorWildMark(){
MCharVector vec;
vec.push_back(FixedMChar("*"));
vec.push_back(FixedMChar("?"));
return vec;
};

//ワイルドカード文字*?
MCharVector markVec(createMCharVectorWildMark());

//*?いづれかを検索する
MChar findWildMark(const char* pattern, const CharSet* charSet){
CharMCharIterator i = mcharIterator(pattern, charSet);
CharMCharIterator end = mcharIterator(pattern + strlen(pattern), charSet);
return *find_first_of(i, end, markVec.begin(), markVec.end());
};



/**
<pre>
ワイルドカードマッチ WildSearch を作成する。
マッチの検索開始位置は文字の先頭 。

【num(番号)について】
WildSearch クラスのnum(番号)の開始の数値。
例えば、patternが"ab*c*d"で、num=1 の場合、 b*cの部分の*は"1"が設定され、
c*dの部分の*は"2"が設定される。これらの数値はコールバックに数値が渡される。
*,?以外を表す WildSearch クラスは固定で番号が設定される。
*,?以外の WildSearch クラス番号は各クラスのNUMで参照する。 
例: TerminatorSearch::NUM とか

【作成された検索を使用したときの例】
a*bの場合:(end= TerminatorSearch のとき)
  ab ⇒マッチする
  akb ⇒マッチする
  kakb ⇒マッチしない
  akbn ⇒マッチしない
</pre>
@param pattern [in]パースする検索パターン(例:"ab*c")
@param charSet [in]文字コード
@param end [in]最後に追加する検索
@param exclude [in]ワイルドカード(*,?)でマッチさせたくない文字。
@param num [in]コールバックのマッチ開始番号。通常は1から始めること。
*/
WildSearchAPtr parseWildCard(const char* pattern, const CharSet* charSet,
WildSearchAPtr end, const MCharVector& exclude, const int& num){
int size = strlen(pattern);
MChar m = findWildMark(pattern, charSet);
WildSearchAPtr ret = end;

//*?が見つかった場合
if(m.pos() < pattern + size){
if(*m.pos() == '*'){
//*を作る
ret = parseWildCard(m.pos() + 1, charSet, ret, exclude, num + 1);
ret.reset(new AstaSearch(num, ret.release(), exclude));
}else{
//?を作る
ret = parseWildCard(m.pos() + 1, charSet, ret, exclude, num + 1);
ret.reset(new QuestionSearch(num, ret.release(), exclude));
}
}

//文字列の部分を作る
int len = m.pos() - pattern;
if(len > 0){
ret.reset(new OnlyStrSearch(OnlyStrSearch::NUM, string(pattern, len), ret.release()));
}

return ret;
};



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

//パース
WildSearchAPtr retAPtr = parseWildCard("ab*c", getCharSet("sjis"),
WildSearchAPtr(new TerminatorSearch()), excludeVec, 1);
scoped_ptr<WildSearch> pattern(retAPtr.release());

cout << "パースによるワイルドカード検索" << endl;

//テスト
search(pattern, "abc");
search(pattern, "abdddc");
search(pattern, "ac");
search(pattern, "abcd");

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










//---------------------------------------------------
//---------------------------------------------------
// ****記事**** 部分一致のワイルドカード検索をするには?
//---------------------------------------------------
//---------------------------------------------------


/**
終わり 。文字列に無関係に検索を終了する。
*/
class FinishSearch : public WildSearch{
public:
enum{NUM=-1, KIND=6};

///
FinishSearch()
: WildSearch(NUM, NULL, KIND) {};

///いつでもtrueを返す
virtual const bool search(SearchPointer& p) const {
p.callback->send(this->num(), p.curPos, 0);
return true;
};
};


//部分一致ワイルドカードのパース
WildSearchAPtr parsePartialWildCard(const char* pattern, const CharSet* charSet){
WildSearchAPtr ret(new FinishSearch());
ret = parseWildCard(pattern, charSet, ret, MCharVector(), 1);
return WildSearchAPtr(new AstaSearch(0, ret.release(), MCharVector()));
};


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

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

cout << "パースによる部分一致ワイルドカード検索" << endl;

//テスト
search(pattern, "abc");
search(pattern, "abdddc");
search(pattern, "ac");
search(pattern, "abcd");

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






//---------------------------------------------------
//---------------------------------------------------
// ****記事**** *や?にマッチした文字列を取得するには?
//---------------------------------------------------
//---------------------------------------------------
#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 main5(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;
};






//---------------------------------------------------
//---------------------------------------------------
// ****記事**** Antパスマッチを実装するには?
//---------------------------------------------------
//---------------------------------------------------
//Antパス除外文字を作る
const MCharVector createAntPathExcludeVec(){
MCharVector vec;
vec.push_back(FixedMChar("/"));
return vec;
};

//除外する文字(スラッシュ)
MCharVector antPathExcludeVec(createAntPathExcludeVec());

///Antパスマッチのパース関数の宣言
WildSearchAPtr parseAntPath(const char* pattern, const CharSet* charSet,
WildSearchAPtr end =WildSearchAPtr(new TerminatorSearch()), const int& num=1);


///Antパスマッチのパース関数実体
WildSearchAPtr parseAntPath(const char* pattern, const CharSet* charSet,
WildSearchAPtr end, const int& num){
int size = strlen(pattern);
MChar m = findWildMark(pattern, charSet);
WildSearchAPtr ret = end;

//*?が見つかった場合
if(m.pos() < pattern + size){
if(strncmp(m.pos(), "**", 2) == 0){
//**を作る
ret = parseAntPath(m.pos() + 2, charSet, ret, num + 1);
ret.reset(new AstaSearch(num, ret.release(), MCharVector()));
}else if(*m.pos() == '*'){
//*を作る
ret = parseAntPath(m.pos() + 1, charSet, ret, num + 1);
ret.reset(new AstaSearch(num, ret.release(), antPathExcludeVec));
}else{
//?を作る
ret = parseAntPath(m.pos() + 1, charSet, end, num + 1);
ret.reset(new QuestionSearch(num, ret.release(), antPathExcludeVec));
}
}

//文字列の部分を作る
int len = m.pos() - pattern;
if(len > 0){
ret.reset(new OnlyStrSearch(OnlyStrSearch::NUM, string(pattern, len), ret.release()));
}

return ret;
};


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

//パース
WildSearchAPtr retAPtr = parseAntPath("/user/*/update/**.cgi", getCharSet("sjis"));
scoped_ptr<WildSearch> pattern(retAPtr.release());

cout << "Antパスのマッチ部分の取得" << endl;

//テスト
const char* str = "/user/00001/update/sell/abc.cgi";
SearchPointer p(str, getCharSet("sjis"), &callback);

//検索
cout << "dose it match?: " << (pattern->search(p) ? "true":"false") << endl;

//
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;
};




int main(int argc, char *argv[]) {
main2(argc, argv);
main3(argc, argv);
main4(argc, argv);
main5(argc, argv);
main7(argc, argv);

return 0;
};