- ベストアンサー
ワイルドカードを用いた文字列検索
皆様こんにちは、 Windows2000+VC6にてワイルドカード(*,?)での文字列比較を 作成したいのですが、そういう関数は無いのですね。 比較対象文字列には2バイト文字も含まれており、*,?自身も 比較できないといけません。 なにか良い方法や、サンプルを教えて頂ければありがたいです。 VBではLIKEで一発だったと思うのに..... VBからCに入ると戸惑うことがいっぱいですね。 よろしくお願い致します。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
- ベストアンサー
再帰関数でこうゆう感じのが有りです→(参考URL) const char *Ptn …ワイルドカード付き文字列 const char *Str …検索対象 戻り値 …1/0:真/偽 int StrMatch( const char *Ptn, const char *Str ) { switch( *Ptn ) { case '\0': return (*Str=='\0'); case '*': return StrMatch( Ptn+1, Str ) || (*Str!='\0') && StrMatch( Ptn, Str+1 ); case '?': return (*Str!='\0') && StrMatch( Ptn+1, Str+1 ); default: return ((unsigned char)*Ptn==(unsigned char)*Str) && StrMatch( Ptn+1, Str+1 ); } }//StrMatch 例: char ptn[] = "?bc*g*"; char str[] = "abcdefgh" int ret; ret = StrMatch( ptn, str ); printf("ret=%d\n", ret); //←ret=1 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ これをマルチバイト(SJIS)対応にする場合、 ・文字列ポインタのインクリメント Ptr+1、Str+1 → _mbsinc(Ptn)、_mbsinc(Str) ・比較のための1文字取得 *Ptr、*Str → _mbsnextc(Ptr)、_mbsnextc(Str) を修正し、 int StrMatchMBS( const unsigned char *Ptn, const unsigned char *Str ) { switch( *Ptn ) { case '\0': return (_mbsnextc(Str)=='\0'); case '*': return StrMatchMBS( _mbsinc(Ptn), Str ) || (_mbsnextc(Str)!='\0') && StrMatchMBS( Ptn, _mbsinc(Str) ); case '?': return (_mbsnextc(Str)!='\0') && StrMatchMBS( _mbsinc(Ptn), _mbsinc(Str) ); default: return (_mbsnextc(Ptn)==_mbsnextc(Str)) && StrMatchMBS( _mbsinc(Ptn), _mbsinc(Str) ); } } 例: char ptn[] = "*o"; // コード…"*" + 0x6f char str[] = "P"; // コード…0x826f int ret, retMBS; ret = StrMatch( ptn, str ); retMBS = StrMatchMBS( ptn, str ); printf("ret=%d retMBS=%d\n", ret, retMBS); //↑ret=1 retMBS=0 // StrMatch の方では、バイト単位比較なので全角1文字「P」と // 半角「*o」が同じとされてしまう。 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ てなところです。既述されているようにC言語に標準 関数では存在しません。 ここの物はシンプルに完成されている関数だと思いますが、 確実かどうかは知りません。ですが、ざっと見たところでは、 LIKE比較で前方後方真中複数ワイルドカード・? 検索、 共に問題は無さそうです。 なんかの役に立てばどうぞ
その他の回答 (2)
- toysmith
- ベストアンサー率37% (570/1525)
共立出版の「ソフトウェア作法」と言う本に正規表現を使った文字列検索のアルゴリズムが解説されています。 Ratforでかかれていますが、RatforはCを意識した文法なので参考になると思います。
お礼
今度本屋をのぞいて見ます。 ありがとうございました。
自分でワイルドマッチの関数を作るのは大変です。 (正規表現のような複雑な物になるとオートマン理論などを知らないとなかなか上手く書けません) なので、誰か賢い人が書いたワイルドカード、正規表現ルーチンをnetで検索して拾ってくるのが賢いやり方かと。 フリーのソフトでソースも公開しているソフトを探してきて流用します。 正規表現の場合、regex.c とか regexp.c なんて名前になってますね。
お礼
検索の仕方が悪いんでしょうが、 ワイルドカードで検索しても思う様にヒットしなくて... ありがとうございました。
お礼
_mbsxxxという関数があるのを初めて知りました。 マルチバイト文字様の関数ですね、参考になります。 ありがとうございます。