aodama.gif(0.97KB) 逆方向からの InStr 関数

 VBScript チュートリアルを見ていたら、InStrRev という文字列の最後から文字列の検索を行う面白そうな関数を見つけました。 文字列の後ろからの検索って、結構重宝しますね。ファイルのフルパスからファイル名のみ抜き出したり、 拡張子だけを抜き出してみたり・・・

 でも私の持っている VB5 には InStrRev 関数はないので、自分で作ってみました。 VB6 の InStrRev 関数にできるだけ近い仕様にしてます。

 ちなみに最初に 1 文字単位で比較しているのは、 処理時間を計測してみた結果、最初から検索文字全てと比較するよりは高速だとわかったからです。 と言っても、1MB のテキストで 0.2 秒くらいの差しか出なかったけどね(笑)。 これも大昔に Pentium 166MHz のマシンで計測したものなので、 現在(2008 年)主流の 1GHz オーバーマシンではほとんど差は出ないでしょう。

 さらに高速化を求める場合は、右端 1 文字の比較処理の後に左端 1 文字の比較を行うなどの処理を追加すると良いでしょう。 またバイナリモードで比較を行う場合は、文字列を数値型配列に代入して数値比較した方が圧倒的に高速でしょう。 私はそこまでやりたくないので、各自改良してお使い下さい(^^;

Option Explicit

'----- InStrRev 関数 Ver 1.02 -----
'
'ある文字列 (strTarget) の中から指定された文字列 (strFind) を
'最後の文字位置から検索を開始し、最初に見つかった文字位置
'(先頭からその位置までの文字数) を返す文字列処理関数です。
'なお、いいかげんに作ったので処理速度は保障しません(^^;
'
'引数 strTarget
'   必ず指定します。検索先の文字列式を指定します。
'
'引数 strFind
'   必ず指定します。検索する文字列式を指定します。
'
'引数 lngStart
'   省略可能です。各検索の開始位置を設定する数式を指定します。
'   引数 lngStart を省略すると -1 が使用され、最後の文字位置から
'   検索を開始します。
'
'引数 lngCompare
'   省略可能です。文字列式を評価するときに使用する文字列比較の
'   モードを表す数値を指定します。
'
'   vbBinaryCompare - バイナリ モードで比較を行います。 (0)
'   vbTextCompare   - テキスト モードで比較を行います。 (1)
'
'   引数 lngCompare を省略すると、バイナリ モードで比較が行われます。
'
'戻り値
'   見つかった文字列の先頭位置を返します。
'   見つからなかった場合や引数に不正な値が指定された場合、0 を返します。
'
'
'Ver 1.02 より、VB6 等の InStrRev 関数に極めて近い仕様に変更しましたので、
'前バージョン以前から使用されている方はご注意下さい。
'といっても lngStart に渡された値による条件分岐が変更になった程度です。
'(lngStart に 0 などの不正な値を渡すと関数を抜けるように変更)
'
Public Function InStrRev _
    (ByRef strTarget As String, _
     ByRef strFind As String, _
     Optional ByVal lngStart As Long = -1, _
     Optional ByVal lngCompare As Long = vbBinaryCompare) As Long

    Dim lngTargetSize As Long                                               '検索対象文字列 (strTarget) のサイズを格納する変数
    Dim lngFindSize As Long                                                 '検索文字列 (strFind) のサイズを格納する変数
    Dim i As Long                                                           'ループカウンタ
    Dim strRight As String                                                  'strFind の最後の 1 文字を格納する変数
 
    lngTargetSize = Len(strTarget)                                          '検索先の文字列のサイズを取得
    If lngTargetSize = 0 Then Exit Function                                 '検索先文字列が 0 文字の場合、関数を抜ける
    lngFindSize = Len(strFind)                                              '検索文字列のサイズを取得
    If lngFindSize = 0 Then Exit Function                                   '検索文字列が 0 文字の場合、関数を抜ける
    
    If lngStart = -1 Then                                                   '検索開始位置に -1(デフォルト) が指定されている場合
        lngStart = lngTargetSize                                            '検索開始位置を検索先文字列の末尾に設定
    ElseIf lngStart < -1 Or lngStart = 0 Or lngStart > lngTargetSize Then   '検索開始位置の値が不正な場合
        Exit Function                                                       '関数を抜ける
    End If
    
    strRight = Right$(strFind, 1)                                           '検索文字列の後ろ 1 文字を抜く

    For i = lngStart To lngFindSize Step -1                                 'lngStart から文字列の最初の方向へループ
        If StrComp(Mid$(strTarget, i, 1), strRight, lngCompare) = 0 Then    '検索文字列の後ろ 1 文字と i 番目の 1 文字が一致した場合
            If lngFindSize = 1 Then                                         '検索文字列が 1 文字の場合
                InStrRev = i                                                'そのまま見つかった位置を返す
                Exit For                                                    'ループを抜ける
            '検索文字列と同じ文字数だけ抜き出し、検索文字列と抜き出した文字列が一致した場合
            ElseIf StrComp(Mid$(strTarget, i - lngFindSize + 1, lngFindSize), strFind, lngCompare) = 0 Then
                InStrRev = i - lngFindSize + 1                              'その文字列の先頭位置を返す
                Exit For                                                    'ループを抜ける
            End If
        End If
    Next i

End Function

サンプル : ダウンロード s_isrev.lzh(2.76KB)


VBコーナーにもどる   トップページにもどる