ページ 11

InStrで"_"(アンダーバー・アンダースコア)を検索したい

Posted: 2008年2月08日(金) 02:50
by 西野孝雄
お久しぶりです。宜しくお願いします。
早速本題ですが例えば
InStr(1, "酸素_AB","_")は2が返ります

最初バグかと思ったのですがバイト単位で見ると"酸"は
&H8E ・
&H5F _
で確かに2で合ってます。

当然5が返ってきて欲しいので
1バイト前の文字を調べ&H81~9F、E0~EFの間かチェックして
2バイト文字なら又続きから検索してチェックしてを繰り返して・・・
とやればいいかなと思ったのですが、非常に効率が悪いと思いました。

_以外でも記号とかの特殊文字で検索した時に起きる現象だと思いますが
皆さんは上記のような方法で文字列検索しているのでしょうか。
他にもっと良い方法をお知りでしたら是非教えて下さい。

AB 4.13
OS XP Home SP2

関係ない話ですが、今までInStrを何度となく使ってきたのに、
今の今まで上記のような事が起こらなかったのは凄いなぁと思っちゃいました。

Posted: 2008年2月08日(金) 11:25
by ゲスト
先人の方が関数を作っていました。
せっかくなので利用させて頂いたら如何ですか?

使用方法はInStrと同じです。

Posted: 2008年2月08日(金) 19:52
by konisi
>1バイト前の文字を調べ&H81~9F、E0~EFの間かチェックして
どうでもいいことですが、4つも比較を書くのは面倒なので

コード: 全て選択

a=buffer
If (&H81<=a and a<=&H9F) or (&HE0<=a and a<=&HEF) then
    continue
End If
と書くところで

コード: 全て選択

a=buffer xor &H20
If &HA1<=a and a<=&HCF then
    continue
End If
と書いてしまいたくなります。

もっといい方法としては、例えば半角仮名文字や全角文字はあまり使われないと言う前提で、
4バイト単位で文字を読み込み、1バイト単位で論理和を取り、
「8ビット目が立っていたら全角文字を含む可能性がある」という判定を行うとか

コード: 全て選択

a=GetDWord(buffer+i)
b=a or (a<<16)
b=b or (b<<8)
If b and &H80 then
    ...'厳密に調べる
Else
    ...'1バイト文字という前提の十分条件が整うので、素早く検索できる。
End If
あるいは、AB以外の実行速度の速い言語(C言語とか)でDLLを作り、呼び出すとか。

Re:InStrで"_"(アンダーバー・アンダースコア)を検索したい

Posted: 2008年2月11日(月) 01:45
by 西野孝雄
返信ありがとうございます

>ゲストさん
コードの切れ端の存在を忘れていました(汗)。
そこを検索してから投稿すればよかったですね。
失礼しました。

>konisiさん
色んなやり方があるもんですね。
取りあえず今はhiraさんのコードを使わせていただくことにしましたが
自分でも色々研究してみたいと思います。