VBAの勉強を始めてみた

色々試しています。

Like演算子でのパターンマッチングについて(Tips-10)

VBA ではRegExpクラスを利用すれば正規表現を使用することができます。
が、そこまでしなくとも Like演算子を使って正規表現のようなパターンマッチングをすることもできます。 

覚えることが少ないので初心者にはオススメですし、組み合わせ次第ではそれなりに複雑なパターンマッチングをすることができます。 

  • 文字列 Like 文字パターン

 

文字列が文字パターンと一致すれば True、一致しなければ False が返ります。

以下は文字パターンに使用する記号の一覧です。たったこれだけなので簡単ですね。

  説明
* 0個以上の文字にマッチ あ* → あ あああ あいうえお などにマッチ
? 1文字にマッチ あ? → あい あお あか など あ で始まる2文字にマッチ
# 1数字にマッチ #個 → 1個 2個 など 数字 で始まり 個 で終わる2文字にマッチ
[ ] [ ]内の1文字にマッチ あいう → あ い う の1文字にマッチ
[!] [ ]内の1文字以外にマッチ !あいう → あ い う 以外の1文字にマッチ
[-] [ ]内の指定した範囲の1文字にマッチ [1-9] → 1 2 3 4 5 6 7 8 9 の1文字にマッチ

 

今回は、このうち [ ]  [ ! ] [ - ] について少し補足しようと思います。

勘違いしがちですが、[ ]は2文字以上の単語を指定することはできません。あくまでも[ ]内に列挙された1文字にマッチします。
どういうことかというと、下のコードでは 東京 という単語にではなく、のいずれか1文字から始まるパターンにマッチします。 なので、東京にもマッチするし京都にもマッチします

Sub test1()
    Debug.Print "東京 "; "東京" Like "[東京]*"
    Debug.Print "京都 "; "京都" Like "[東京]*"
End Sub

f:id:kouten0430:20181215172634j:plain

 

,(カンマ)で区切っても2文字以上の単語を指定することはできません。,(カンマ)も1文字として比較対象になるからです。
下のコードでは、東京大阪という2つの単語にではなく、東 京 ,   のいずれか1文字から始まるパターンにマッチします。

Sub test2()
    Debug.Print "東海 "; "東海" Like "[東京,大阪]*"
    Debug.Print "京浜 "; "京浜" Like "[東京,大阪]*"
    Debug.Print ", "; "," Like "[東京,大阪]*"
    Debug.Print "大仏 "; "大仏" Like "[東京,大阪]*"
    Debug.Print "阪神 "; "阪神" Like "[東京,大阪]*"
End Sub

f:id:kouten0430:20181215172730j:plain

 

文字と文字の間に -(ハイフン)を入れると文字の範囲内の1文字にマッチします。
例えば、[1-9]であれば、1~9 のいずれかにマッチし、[A-Z]であれば、A~Zのいずれかにマッチするということです。[9-1]のように降順だとエラーになります。

でも、文字の範囲って何なのさ?と、思うかもしれません。

確かに、分からないまま使用するのは気持ちの悪いものなので、少し具体的にいうと

文字コードの指定範囲(昇順)

ということになります。
下は文字コード表の一部ですが、[1-9]であれば文字コード 31 ~ 39 の範囲内、[A-Z]であれば文字コード 41 ~ 5A の範囲内の1文字と比較します。

f:id:kouten0430:20181215172826j:plain

 

ちょっと実験してみましょう。
[0-o]の範囲であれば、文字コード表の 30 ~ 6F の範囲が True その前後が False になるはずです。 

Chr関数で文字コード 21 ~ 7E を [0-o] と比較して結果を見てみましょう。

Sub test3()
    For i = &H21 To &H7E
        Debug.Print Chr(i); " "; Chr(i) Like "[0-o]"
    Next i
End Sub

f:id:kouten0430:20181215172947j:plain

 

ふむふむ。確かに、文字コードの昇順のようですね。
当然、小文字と大文字は文字コードが違うので区別されています。

これを [!0-o] とすれば、True と False が逆になる訳です。

 

今回、モジュール内の文字列比較方法を省略したので比較方法が Binary でしたが、 比較方法が Text の場合についても書いておこうと思います。その辺は次回以降に。