大文字と小文字を区別して検索したい
正規表現を使用して文字列を検索したい
こんにちは!フリーランスの長野です。
VBAである文字列の中に指定の文字列が含まれているか検索したい場合、InStr関数を使用します。この記事ではそんなInStr関数について、使い方の基礎から応用的な使い方まで6つのステップでわかりやすく解説していきます。
今回はInStr関数について、基礎から応用までをわかりやすく解説していきますのでぜひ参考にしてください。
VBAのInStr関数とは
InStr関数は、特定の文字列が別の文字列内で最初に見つかった位置を返します。なお、戻り値の型はVariant型です。
InStr関数は以下のように記述して使用します。
InStr([start, ]string1, string2[, compare])
引数の中で「[ ]」で囲まれた部分は省略することができます。引数の指定について表にまとめました。
引数 | 定数(値) | 説明 |
---|---|---|
start | ー | 各検索の開始位置を設定する数式を指定 省略すると、先頭の文字から検索 Null が含まれている場合はエラーが発生 引数 compareが指定されている場合は必須 |
string1 | ー | 検索先の文字列 |
string2 | ー | 検索する文字列 |
compare | vbUseCompareOption(-1) | Option Compare ステートメントの設定を使用して比較 |
vbBinaryCompare(0) | バイナリで比較 | |
vbTextCompare(1) | テキストで比較 大文字、小文字の区別なし 全角、半角の区別なし |
戻り値は引数の指定によって変わってくるので、これも表にまとめます。
条件 | 戻り値 |
---|---|
string1の長さが0 | 0 |
string1がNull | Null |
string2の長さが0 | start |
string2がNull | Null |
string2がみつからない | 0 |
string2がstring1内でみつかった | 最初にみつかった位置 |
startの値がstring2の文字数より大きいとき | 0 |
引数のstring1の中にstring2が複数存在するときは、最初にみつかった位置を返します。
なお、バイト型のデータが格納された文字列の場合はInStrB関数を使用します。InStrB関数は最初にみつかったバイト位置を返します。
VBAのInStr関数の使い方
ここではVBAのInStr関数について、基本的な使い方から応用的な使い方まで6つのパターンを解説していきます。
InStr関数の基本的な使い方
それでは基本的な使い方についてみていきましょう。以下のサンプルコードをご覧ください。
Sub macro1() Dim string1 As String, string2 As String string1 = "侍エンジニア" string2 = "塾" MsgBox "「" & string2 & "」の位置は" & InStr(string1, string2) & "番目" End Sub
このサンプルコードでは、InStr関数を使って文字列string1からstring2の位置を取得しています。
InStrRev関数の使い方
InStr関数を使う場合、文字列の前方から検索して位置を取得することができます。それでは文字列の後方から検索して位置を取得したい場合はどうすればいいのでしょうか?
そんな場合はInStrRev関数を使います。
後方からの検索ですので検索先の文字列の中に指定の文字列が複数含まれている場合などに、一番後ろの文字列の位置を前方からの順番で取得することができます。
InStrRev関数は以下のように記述します。
InstrRev(string1, string2 [, start[, compare]])
引数の中で「[ ]」で囲まれた部分は省略することができます。InStrRev関数の引数の指定順はInStr関数とは違うので、注意しましょう!
引数、戻り値の説明についてはInStr関数と同じですので、さきほどの章の表を参考にしてくださいね。
それではサンプルコードで確認していきましょう。
Sub macro2() Dim string1 As String, string2 As String string1 = "侍エンジニア侍エンジニア" string2 = "塾" Dim position As Integer position = InStrRev(string1, string2) If position > 0 Then MsgBox "後方からの検索では「" & string2 & "」の位置は" & position & "番目" Else
MsgBox "「" & string2 & "」は見つかりませんでした。" End If End Sub
このサンプルコードでは、InStrRev関数を使って文字列string1から文字列string2を後方から検索しています。後方からの検索ですので、一番後ろの文字列の位置が前方からの順番で返ってきています。
Left関数、Mid関数との組み合わせ
InStr関数を使うと含まれる文字列の位置が取得できるので、その位置情報を元に文字列を分割することができます。文字列を分割する関数にはSplit関数がありますが、Split関数の場合は指定の区切り文字1文字での分割になります。
これに対してInStr関数を使うと指定の文字列で分割することができます。InStr関数を使って文字列を分割する場合、Left関数やMid関数などを使って分割後の文字列を取得することになります。
Left関数は文字列の先頭から、指定した文字数文の文字列を抜き出して返します。
Left関数は以下のように記述します。
Left(string, length)
- 引数のstringには、抜き出す元の文字列を指定します。
- 引数のlengthには、抜き出す文字数を指定します。
- Mid関数は文字列から抜き出す先頭位置を指定し、指定文字数文を抜き出して返します。
Mid関数は以下のように記述します。
Mid(string, start[, length])
- 引数のstringには、抜き出す元の文字列を指定します。
- 引数のstartには、抜き出す先頭位置を指定します。
- 引数のlengthには、抜き出す文字数を指定します。
- 引数のlengthは記述を省略することができます。
それではサンプルコードで確認していきましょう。
Sub macro3() Dim string1 As String, string2 As String string1 = "侍エンジニア" string2 = "エンジニア" 'string2の位置を取得 Dim num As Variant num = InStr(string1, string2) If num > 0 Then '分割後の文字列を取得 Dim msg1 As String, msg2 As String msg1 = Left(string1, num - 1) msg2 = Mid(string1, num + Len(string2)) MsgBox msg1 & ", " & msg2 Else MsgBox "「" & string2 & "」は「" & string1 & "」に見つかりませんでした。" End If End Sub
このサンプルコードでは、InStr関数を使って文字列string1から文字列string2の位置を取得しています。
またLeft関数を使って、string1からstring2より前の文字列を抜き出しています。さらにMid関数を使って、string2より後の文字列を抜き出しています。
Mid関数を使って抜き出す際には、string2の文字列数をLen関数を使って算出し、抜き出す先頭位置を指定しています。Mid関数や、Left関数、Right関数とInStr関数を組み合わせて使う方法については、こちらのサイトで詳しく解説しています。
文字列中に複数含まれる場合
これまでは、検索する対象の文字列中に検索したい文字列が1つ含まれる場合についてお伝えしてきました。もし、検索したい文字列が2つ以上含まれている場合はどうしたらいいのでしょうか?
検索したい文字列が2つ以上含まれている場合について、サンプルコードで確認していきましょう。
Sub macro7() Dim string1 As String, string2 As String string1 = "侍エンジニア侍エンジニア侍エンジニア" string2 = "塾" Dim i As Integer, msg As String i = InStr(1, string1, string2) ' 最初の検索を 1 から開始するように修正 Do While i > 0 msg = msg & i & ", " i = InStr(i + 1, string1, string2) Loop If Len(msg) > 0 Then ' 見つかった場合は最後の ", " を削除 msg = Left(msg, Len(msg) - 2) MsgBox "「" & string2 & "」の位置は" & msg & "番目" Else ' 見つからなかった場合 MsgBox "「" & string2 & "」は見つかりませんでした。" End If End Sub
実行結果:
InStr関数は第1引数で検索のスタート位置を指定することができます。検索対象となる文字列に検索したい文字列が複数含まれる場合は、見つかった位置の1つ後ろの位置から検索を再び行えば次の位置を検索することができます。
これを見つからなくなるまでループで繰り返します。InStr関数は見つからなくなると0(ゼロ)を返しますので、戻り値が0(ゼロ)になるまで繰り返すことで、すべての位置を取得することができます。
複数の文字列で検索する方法
InStr関数は複数の文字列で検索することはできません。複数の文字列で検索する場合は論理演算子のOrやAndを使う必要があります。
サンプルコードで確認しましょう。
Sub macro4() Dim string1 As String, string2 As String, string3 As String string1 = "侍エンジニア" string2 = "侍" string3 = "塾" Dim msg As String 'Or検索 If InStr(string1, string2) <> 0 Or InStr(string1, string3) <> 0 Then msg = msg & "「" & string2 & "」もしくは「" & string3 & "」がみつかりました" & vbCrLf Else msg = msg & "「" & string2 & "」、「" & string3 & "」どちらもみつかりません" & vbCrLf End If 'And検索 If InStr(string1, string2) <> 0 And InStr(string1, string3) <> 0 Then msg = msg & "「" & string2 & "」、「" & string3 & "」どちらもみつかりました" & vbCrLf Else msg = msg & "「" & string2 & "」、「" & string3 & "」どちらかもしくは両方みつかりません" & vbCrLf End If MsgBox msg End Sub
大文字と小文字の区別について
InStr関数は引数を設定しなければ、大文字と小文字を区別して位置を返します。大文字と小文字の区別をなしにしたい場合は、引数のcompareをvbTextCompareに指定します。
なお、引数のcompareを指定する場合は引数のstartを指定する必要があります。
サンプルコードで確認しましょう!
Sub macro5() Dim string1 As String, string2 As String string1 = "Hello VBA!" string2 = "vba" Dim num As Variant, msg As String 'バイナリで比較 num = InStr(string1, string2) If num <> 0 Then msg = msg & "「" & string2 & "」の位置は" & num & "番目" & vbCrLf Else msg = msg & "「" & string2 & "」はみつかりませんでした" & vbCrLf End If 'テキストで比較 num = InStr(1, string1, string2, vbTextCompare) If num <> 0 Then msg = msg & "「" & string2 & "」の位置は" & num & "番目" & vbCrLf Else msg = msg & "「" & string2 & "」はみつかりませんでした" & vbCrLf End If MsgBox msg End Sub
このサンプルコードでは、InStr関数を使って文字列string1から文字列string2の位置を取得しています。string2は「vba」と小文字の文字列ですが、string1には「VBA」と大文字の文字列であれば含まれています。
InStr関数の引数compareを指定しない場合は、バイナリで比較が行われ大文字と小文字を区別しstring2の位置はみつかっていません。引数のcompareをvbTextCompareで指定した場合は、テキストで比較が行われ大文字と小文字を区別せずにstring2の位置がみつかっています。
ワイルドカードや正規表現の使用について
InStr関数では正規表現を指定して使用することはできません。
代わりにLike演算子とワイルドカードを使う方法についてご紹介します。
ワイルドカードとは、あるパターンにマッチするように表現した文字列のことです。
ワイルドカードで使える文字は、正規表現で使える文字に比べて少ないので、正規表現に比べて表現できるパターンには制限がありますが、正規表現をワイルドカードで代替できることも多いです。
サンプルコードで確認しましょう。
Sub macro6() Dim string1 As String, string2 As String string1 = "侍エンジニア" string2 = "侍*塾*" ' Likeを使用せず、InStrで比較 If InStr(string1, "侍") > 0 And InStr(string1, "塾") > 0 Then MsgBox "「" & string2 & "」がみつかりました" Else MsgBox "「" & string2 & "」がみつかりません" End If End Sub
このサンプルコードでは、文字列string2に「*」(アスタリスク)が含まれています。Like演算子では、「*」(アスタリスク)などのワイルドカードを使った部分的に合致した場合の条件分岐を記述することができます。
string1の「侍エンジニア」はstring2の「侍*塾*」のパターンと一致しますので、Trueが返ってきています。ワイルドカードでは「*」(アスタリスク)の他にも以下の表のような文字を使って、マッチングのパターンを指定することができます。
文字 | 説明 |
---|---|
? | 任意の1文字 |
* | 0文字以上の文字 |
# | 0~9の半角数字 |
[charlist] | charlistに含まれる全角または半角の1文字 |
[!charlist] | charlistに含まれない全角または半角の1文字 |
Like演算子とワイルドカードの使い方については、こちらのサイトで詳しく解説しています。
まとめ
ここでは、InStr関数、InStrRev関数の使い方について説明しました。InStr関数を使うと含まれる文字列の位置を取得することができるので、その位置を使って分割などの文字列操作もできるようになります。
使いこなすことができるように、この記事を何度も参考にして下さいね!