InStr関数で文字列の位置を先頭から調べる
今回の目標
「文字列を先頭から検索したい!」や「InStr関数とInstrRev関数は何が違うの?」と疑問を持ったあなたへ。
この記事では、InStr関数の使い方から、InstrRev関数の違いを、まとめて丁寧に解説します!
基本的なだけでなく、実務で使える具体例つきです。
目標リスト
- InStr関数について、理解する
- InStr関数とInstrRev関数の違いを理解する
InStr関数について
InStr関数とは
InStr関数は、文字列内で特定の文字列が先頭から数えて何番目にあるかを返します。
もし、文字列の中に調べたい文字が含まれていなかった場合は、数字の「0」を返します。
文字「ABCABC」で、文字「A」をInStr関数を使用すると、「1」が返ります。
例えば、メールアドレスの「@」までの位置(ローカル部)と「@」より後(ドメイン部)を分ける場合に使用します。
InStr関数の引数一覧と戻り値
InStr関数の構文
InStr(start, string1, string2, compare)
InStr関数の引数一覧
InStr関数の構文と引数一覧です。
※一部、Microsoft社のリファレンスを参照しています。
【Microsoft公式】
InStr 関数
名前 | 省略 | 規定値 | 説明 |
---|---|---|---|
start | 可能 | 1 | 何文字目から検索するか(検索開始位置) |
string1 | 不可 | - | 検索する文字列(検索文字) |
string2 | 不可 | - | 検索対象の文字列(被検索文字) |
compare | 可能 | vbBinaryCompare | 大文字・小文字、全角・半角が違っても置換をするか。規定値の場合、文字種が違うと、検索対象にならない。 |
引数「compare」の定数一覧です(実用的な定数のみ記載します)。
名前 | 値 | 説明 |
---|---|---|
vbBinaryCompare | 0 | 大文字・小文字、全角・半角が異なる場合、検索対象としない |
vbTextCompare | 1 | 大文字・小文字、全角・半角が異なる場合、検索対象とする |
使用サンプル
1.メールアドレスの「@」の位置を取得する
メールアドレスの「@」の位置を取得します。
今回は他関数との連携例として、「@」より前(ローカル部)及び、「@」より後ろ(ドメイン部)も取得します。
ローカル部はLeft関数、ドメイン部はMid関数で取得すると良いでしょう。
サンプルコード
Sub SampleInStr1()
Dim mailAddress As String
Dim mailLocal As String
Dim mailDomain As String
Dim sepPos As Long
mailAddress = "hogefuga@example.com"
'@ が何文字目か取得する
sepPos = InStr(mailAddress, "@")
' ローカル部を抽出する
mailLocal = Left(mailAddress, sepPos - 1)
' ドメイン部を抽出する
mailDomain = Mid(mailAddress, sepPos + 1)
' イミディエイトウィンドウ(Ctrl + G)に表示
Debug.Print "メールアドレス:" & mailAddress
Debug.Print "@ が何文字目か:" & sepPos
Debug.Print "ローカル部 :" & mailLocal
Debug.Print "ドメイン部 :" & mailDomain
End Sub
メールアドレス:hogefuga@example.com
@ が何文字目か:9
ローカル部 :hogefuga
ドメイン部 :example.com
2.スペース区切りのデータを切り分ける
スペース区切りやカンマ区切り等でデータを分けている場合、その位置が分かります。
次のサンプルコードは、ファーストネームを取得します。
サンプルコード
Sub SampleInStr2()
Dim fullName As String
Dim firstName As String
Dim sepPos As Long
' John Michael Smith(ジョン・マイケル・スミス)
fullName = "John Michael Smith"
' 最初のスペースの位置を取得する
sepPos = InStr(fullName, " ")
' ファーストネームを抽出する
firstName = Left(fullName, sepPos - 1)
' イミディエイトウィンドウ(Ctrl + G)に表示
Debug.Print "本名:" & fullName
Debug.Print "スペースが何文字目か:" & sepPos
Debug.Print "ファーストネーム :" & firstName
End Sub
本名:John Michael Smith
スペースが何文字目か:5
ファーストネーム :John
3.ファイル名で使用できない文字がないか確認する
Windowsの場合、ファイル名として使用できない文字が複数あります。
これが、文字列中に含まれていないかを確認できます。
サンプルコード
Sub SampleInStr3()
Dim arr() As Variant
Dim var As Variant
Dim invalStr As String 'inval = invalid
Dim fileName As String
fileName = "abc/>.txt"
'Windowsの場合
arr = Array("\", "/", ":", "*", "?", """", "<", ">", "|")
For Each var In arr
If 0 < InStr(fileName, var) Then
'ファイル名に含まれてる「使用できない文字」を記録する
invalStr = IIf(invalStr <> "", invalStr & ",", "") & var
End If
Next var
If invalStr <> "" Then
Debug.Print "文字【" & invalStr & "】が含まれています!"
Else
Debug.Print "ファイル名として使用できます!"
End If
End Sub
文字【/,>】が含まれています!
4.大文字小文字や、全角半角を区別せずに位置を取得する
InStr関数は、文字列と検索する文字の大文字・小文字や全角・半角が異なると位置を取得できません。
しかし、InStr関数の第4引数に「vbTextCompare」を指定することで、大文字小文字および全角半角の違いを無視して、位置を取得できます。
なお、第4引数を指定する場合は、第1引数を省略できません。
サンプルコード
Sub SampleInStr4()
Dim str As String
Dim posBinaryCompare As Long
Dim posTextCompare As Long
str = "abcabc"
posBinaryCompare = InStr(str, "B")
posTextCompare = InStr(1, str, "B", vbTextCompare)
Debug.Print "posBinaryCompare:" & posBinaryCompare
Debug.Print "posTextCompare:" & posTextCompare
End Sub
posBinaryCompare:0
posTextCompare:2
5. 2回目以降の特定の文字列の位置を取得する
InStr関数の第1引数は「何文字目から検索を開始するか」です。
例えば、文字「ABAB」から、文字「B」の2回目が何文字目にあるかを調べたい場合、1回目のBが何文字目にあるかを調べ、最初に見つかった位置の直後から再度検索することで2回目の文字「B」の位置を取得できます。
サンプルコード
Sub SampleInStr5_1()
Dim str As String
Dim search As String
Dim pos As Long
search = "c"
str = "abcabcabcabc"
'1回目の位置
pos = InStr(str, search)
'2回目の位置
pos = InStr(pos + 1, str, search)
Debug.Print "2回目の 'c' の位置:" & pos & "文字目"
End Sub
2回目の 'c' の位置:6文字目
検索文字が3回目以降の場合
例えば、文字「abababab」において、「b」の3回目の位置を取得したいとします。
先とサンプルの様に、InStr関数をステップごとに記載するとプログラムが長くなってしまいます。
その場合は、For文を用いることでコードを簡潔にできます。
サンプルコード
Sub SampleInStr5_2()
Dim str As String
Dim search As String
Dim show As String
Dim i As Long
Dim num As Long '何回目、検索するか
Dim pos As Long
search = "c"
num = 3 '「3」回目の文字cの位置を検索する
str = "abcabcabcabc"
'文字を検索する
For i = 1 To num
pos = InStr(pos + 1, str, search)
Next i
If 0 < pos Then
show = num & "回目の文字" & search & "は" & pos & "文字目にあります。"
Else
show = "文字" & search & "は、文字列中に" & num & "個、存在しません。"
End If
Debug.Print show
End Sub
3回目の文字cは9文字目にあります。
InStr関数とInstrRev関数の違いと使い分け
機能などの違いについて
関数名について
関数名の表記に違いがあります。
InStr関数は『S』が大文字ですが、InstrRev関数は『s』が小文字です。
関数の機能の違いについて
先頭から検索する関数は、本記事で紹介した「InStr関数」です。
末尾から検索する関数は、「InstrRev関数」です。
引数の位置について
InStr関数と、InstrRev関数 で引数のデータ自体は同じですが、順番が異なります。
-
InStr関数(何文字目から検索するか, 被検索文字, 検索文字, 比較種類)
-
InstrRev関数(被検索文字, 検索文字, 何文字目から検索するか, 比較種類)
上記の通り、「何文字目から検索するか(検索開始位置)」の位置が異なります。
InStr関数とInstrRev関数の使い分け
特定の文字が含まれているかどうかを確認するだけであれば、どちらの関数を使っても同じ結果が得られます。
それに対し、フルパスからファイル名を取得する、などの取得する位置が重要な場合は使い分けが必要です。
-
InStr関数
・外国人のファーストネームを取得する
※ ファーストネーム、ミドルネーム、ラストネームがあるときに有用
・電話番号の市外局番を取得する
-
InstrRev関数
・フルパスからファイル名を取得する
・拡張子を取得する
注意点(戻り値、InstrRev関数との動作の違い等)
InStr関数の注意点は以下の通りです。
赤の太字は、InstrRev関数と挙動が異なるので注意しましょう。
被検索文字について
- 被検索文字が空文字("")の場合、『0』を返す
- 被検索文字が「Null」の場合、『Null』を返す
- 被検索文字が「Nothing」の場合、実行時エラー91が発生する
検索文字について
- 検索文字が空文字("")の場合、検索開始位置を返す
- 検索文字が「Null」の場合、『Null』を返す
- 検索文字が「Nothing」の場合、実行時エラー91が発生する
検索開始位置について
-
検索開始位置が被検索文字の長さより長いと、『0』を返す。
ただし、検索文字が空文字("")の場合、検索開始位置を返す。
※ InstrRev関数は、検索文字が空文字("")の場合でも、『0』を返す。 -
検索開始位置が「0」以下の場合、実行時エラー5が発生する。
ただし、被検索文字か、検索文字が空文字("")の場合、『0』を返す。 -
検索開始位置が小数の場合、CInt関数の丸めの変換が行われる。
例)2.50 → 2、 2.51 → 3、 3.5 → 4、 4.5 → 4
発生する可能性があるエラーについて
実行時エラー5
プロシージャの呼び出し、または引数が不正です。
実行時エラー91
オブジェクト変数または With ブロック変数が設定されていません。
実行時エラー94
Null の使い方が不正です。