• ベストアンサー

ワイルドカードを用いた文字列検索

皆様こんにちは、 Windows2000+VC6にてワイルドカード(*,?)での文字列比較を 作成したいのですが、そういう関数は無いのですね。 比較対象文字列には2バイト文字も含まれており、*,?自身も 比較できないといけません。 なにか良い方法や、サンプルを教えて頂ければありがたいです。 VBではLIKEで一発だったと思うのに..... VBからCに入ると戸惑うことがいっぱいですね。 よろしくお願い致します。

質問者が選んだベストアンサー

  • ベストアンサー
noname#2009
noname#2009
回答No.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比較で前方後方真中複数ワイルドカード・? 検索、 共に問題は無さそうです。 なんかの役に立てばどうぞ

参考URL:
http://www.hidecnet.ne.jp/~sinzan/tips/c/c_tip03.htm
hiroshi2001
質問者

お礼

_mbsxxxという関数があるのを初めて知りました。 マルチバイト文字様の関数ですね、参考になります。 ありがとうございます。

その他の回答 (2)

  • toysmith
  • ベストアンサー率37% (570/1525)
回答No.2

共立出版の「ソフトウェア作法」と言う本に正規表現を使った文字列検索のアルゴリズムが解説されています。 Ratforでかかれていますが、RatforはCを意識した文法なので参考になると思います。

参考URL:
http://kyoritsu-pub.topica.ne.jp/bookhtml/0306/000604.html
hiroshi2001
質問者

お礼

今度本屋をのぞいて見ます。 ありがとうございました。

noname#11476
noname#11476
回答No.1

自分でワイルドマッチの関数を作るのは大変です。 (正規表現のような複雑な物になるとオートマン理論などを知らないとなかなか上手く書けません) なので、誰か賢い人が書いたワイルドカード、正規表現ルーチンをnetで検索して拾ってくるのが賢いやり方かと。 フリーのソフトでソースも公開しているソフトを探してきて流用します。 正規表現の場合、regex.c とか regexp.c なんて名前になってますね。

hiroshi2001
質問者

お礼

検索の仕方が悪いんでしょうが、 ワイルドカードで検索しても思う様にヒットしなくて... ありがとうございました。

関連するQ&A

  • 文字列から文字列を検索するプログラム

    現在、C言語を学習しています。 文字列から文字列を検索する関数に「strstr]がありますが、自作関数として自分で作成する方法を考えております。 文字列から文字を検索する事は出来たのですが、文字列を検索するシーケンスがわかりません。 有識者の方、御教授よろしく御願い致します。

  • C♯で文字列を切り出すには?

    C♯の文字列操作について教えてください。 "あいうえお"という文字列があったら、"あ"だけ 切り取って、"いうえお"という文字列がほしいのですが、 どのようにしたら良いのでしょうか? VB.NETでいう、midのようなものがあるかと思ったのですが、 見当たらず…。 サンプルを交えて教えていただけると助かります。 宜しくお願いします。

  • Excelで文字列をワイルドカード検索して対象文字があれば○を入れる

    Excelで文字列をワイルドカード検索して 対象文字があれば「○」を入れたいのですが 関数もマクロもいいものが見つかりません。 ※Excel98です。 なにかありませんでしょうか。 例:セル内に「チョコレート」という文字があれば隣の列に「○」を入れる。 チョコレートたべたい。⇒○ 飴が食べたい。⇒× チョコレートが買いたい。⇒○ わかる方、どうぞよろしくお願い致します。

  • 文字列検索について

    文字列から検索対象文字がいくつあるかカウントする関数はありますでしょうか? strTest という変数からchar(10)の改行文字のカウントをしたいのですが。

  • 文字列の比較について

    お世話になります。 次のような文字列の比較を考えているのですが 123456789 123456ABC89 この場合、ABCを7に置き換えると文字列が一致する ので、「7」と「ABC」を取り出したいのですが、 どのように調べたらよいでしょうか? VBはいろいろと関数も用意されているので、現在は instrとinstrrevを使って相違のある場所を調べようと していますがなかなか思うようにいきません。 お願いします。

  • 文字列の変換

    超 C++ 初心者です。 コンソールで "Hello, world!" を学んでからニ,三ヶ月程度です。 C++ の string クラスのメンバ関数 c_str() を用いることで /**  * string(C++ の文字列)から C の文字列(文字配列)を取り出し  * その先頭のアドレスを返す  */ ということができるのを学びました。 今 C++ の string および VC++ の CString の変換をしたいと思っています。 例えば VC++ で MFC アプリケーションを作っているとき, C++ の string である temp を VC++ の CString として使えるように するには,どういう手段をとればよいのでしょうか。 逆に VC++ の CString である temp を C++ の string として使うとき の方法もご教授ねがえれば幸いです。 超初心者につき,方法があまりにも難しいようでしたら断念することも考えています。

  • 文字列の中に2バイトが含まれているか調べたい

    文字列の中に、2バイト(つまり全角)が含まれているかどうかを調べたいです。 VBなどでは、LenB(StrConv(Value, vbFromUnicode))とかで、調べられるのですが、Pealではどのような関数を用いれば良いでしょうか・ 最適な関数、あるいは手法があれば、教えてくださいませ。 よろしくお願いします。

    • ベストアンサー
    • Perl
  • CSVの項目検索について

    現在C++を使いはじめて1週間になり、そこで任されたプログラムの一部がわからずに困っています。 概要: ・CSVファイルがありそこの、ある項目列と検索する文字列が一致すれば、一致したレコードを取得するといった部分で煮詰まっています・・・ CSVファイルのサンプル testA,1,200412 testB,2,200410 testC,3,200409 といった感じで、「testA」といった文字列で検索をかけ「testA,1,200412」といったようにその対象となるレコードを取得したいのです。 今はWinAPIを使って作成すると言ったことから CreateFileなどの関数でCSVを読み込むところまで出来ましたが、要領がわからず調べても要領がわからずに1日無駄にすごしてしまいました、そこで どなたかアドバイスをもらえればと思い質問いたしました。 環境はVC++6.0です、よろしくお願いします。

  • VLOOKUPで●●を含む文字列を検索したい

    VLOOKUP関数を使って、検索値をD列、範囲をAB列にして、 B列の値段をE列に表示させたいと思っています。     A列        B列  C列     D列     E列 おいしいオレンジジュース   150 りんごジュース りんごジュース 天然果汁   200 オレンジジュース 検索範囲の文字には検索値の文字が含まれてはいるのですが、前や後ろ、もしくは前後両方に文字が追加されています。 あれこれ調べましたが、逆の条件の場合は他の関数+ワイルドカードの組み合わせでできるようでしたが、 自分がやりたいことは調べきれず、質問させていただきました。 一応、TRUE、FALSEで切り替えて検索してみたのですが、希望している結果とは違うものが出てしまいました。 (同じ結果が何度もダブって出る。データ的に1対1しかないのに) 文字列の場合のVLOOKUP関数のTRUE、FALSEの定義もよくわかりません。

  • VC++ 文字列のDate型チェック

    こんばんは。 VC++でVBのIsDateのような使い方をする関数 CString または CHar配列などの文字列がDate型かどうか チェックする関数を探しています。 MFCとかにないのでしょうか? 2006/05/26とかのチェックは一文字づつ抜き出して xxx/xx/xxという形はチェックできるのですが うるう年とか考慮すると自作だとかなり複雑なものになってしまいそう なので・・・ どなたかお分かりになる方、よろしくお願いします。

専門家に質問してみよう