Visual Basic InStr

InStr is a powerful VB string function. It's the perfect way to search and test strings in robust Visual Basic 6.0 applications. This article shows how to call InStr to perform advanced text processing tasks quickly. The article also discusses case insensitivity, vbTextCompare, Option Compare Text and InStr related bugs.

VB6 statements and constants in this article: InStr, InStrB, InStrRev, Option Compare, vbBinaryCompare, vbTextCompare.

InStr syntax

InStr returns the first occurrence of a string inside another string.

InStr([start,] string1, string2 [, compare])
start
Optional. Character position where the search starts. If omitted, the search starts at the start of string1, position 1. Valid input values: 1 to Len(string1)
string1
The string to search in. Can be Null.
string2
The string to find. This is the text you want to find inside string1. It is usually shorter than string1. Can be Null.
compare
Optional. Specifies the type of string comparison.
  • vbBinaryCompare (0) performs a fast binary comparison where each character matches only itself. This is the default.
  • vbTextCompare (1) performs a text comparison.
  • vbDatabaseCompare (2). For Microsoft Access (Windows only), performs a comparison based on information contained in your database.
  • If you omit compare, InStr will use the setting of the Option Compare statement.
Binary comparison is the safest option. Text comparison rules vary by the system locale. In text comparison, what matches on one computer may not match on another.

Return value

InStr returns one of the following values:
  • Null if either string1 or string2 is Null.
  • start if string2 is empty.
  • Character position of the first occurrence of string2 in string1.
  • Zero if string2 was not found in string1.
Special cases:
  • InStr(string1, "") returns 1 if string1 is not empty.
  • InStr("", "") returns 0.
  • If start exceeds the length of string1, there is never a match and InStr returns 0.

Crash warning. The Null return value is a catch. If your code is not prepared to receive a Null, it may crash. You can only receive a Null if you are passing Variant data to InStr and if the data can contain a Null. If you are only passing String data, you are safe.

Basic uses of InStr

In the following examples we assume that Option Compare Binary is in effect. This is the default setting.

Locate text inside a string

position = InStr("avbprogram", "vb")   ' Returns 2
position = InStr("avbprogramvb", "vb") ' Also returns 2

Locate the first character in a string

position = InStr("avbprogram", "v")    ' Returns 2

Search in the rest of the string

The start parameter is useful to skip the start of the string. This allows us to skip known instances of the search string.

position = InStr(4, "avbprogramvb", "vb") ' Returns 11

It is also useful for optimizing calls to InStr. If we can start in the middle, the search will perform faster.

Test for existence of a substring

InStr is a quick and handy way to test whether a string contains another string. When the return value is positive, the string exists. When it is zero, it doesn't exist. The return value cannot be negative. The operator <> is the fastest way to decide between zero and positive.

exists = InStr("avbprogram", "vb") <> 0

Test for non-existence of a substring

If we want to make sure certain text does not exist inside another string, we simply reverse the existence test.

notexists = InStr("avbprogram", "vb") = 0

Text comparison: Beware!

Bug warning. The vbTextCompare parameter and Option Compare Text are full of surprises. Text comparison performs a case-insensitive search, but it also adds new effects which aren't quite visible. This is a potential source of hidden bugs.

Did you know that InStr(1,"Strae","ss",vbTextCompare) locates "" at position 5? You searched for 2 characters, but InStr found just one! What is this? The character "" stands for "ss" in the German language. But, if your program was expecting the 2 characters "ss" or "SS", it can fail now.

Similarly, InStr(1,"Þingvellir","th",vbTextCompare) locates "Þ". This happens because the character "Þ" stands for "TH" in Icelandic. To InStr, the input reads "THingvellir". Again, you searched for 2 characters, but InStr found just one.

How text comparison works

InStr with text comparison works with the following rules:
  1. Perform a case insensitive search
  2. with the following characters expanded:
    => ss, => th, => ae, œ => oe.

Due to rule 2, the following characters are unsafe: a, e, h, o, s, t. They are unsafe if any of the following characters can be expected in the input: Œœ. One can expect them in systems processing (foreign) names and addresses, for example.

As it happens, the following expressions are not equal, even though they could be. This means InStr will not locate them in place of the other:
  • ø, oe and
  • æ and
  • , aa and o
  • , d, dh and th
  • e and
  • ij and ij (Dutch ligature vs. separate characters)
  • i and İ (Turkish dotted İ)
  • ı and I (Turkish dotless I)
  • © and (c)
  • and 2
  • and 1/2
  • ... and many more.

Case insensitivity extends itself to a total of 673 Unicode characters. This includes all Latin characters and Latin characters with diacritic marks. It also includes Greek, Cyrillic, Armenian and Georgian characters and Unicode Roman numbers.

Text comparison examples

  • InStr(1,"Ætna","et",vbTextCompare) returns 1. Note how the match happens "in the middle" of the AE ligature.
  • InStr(1,"Fjrland","ja",vbTextCompare) returns 2. Note how the match happens for the "first half" of the ae ligature.
  • InStr(1,"i","is",vbTextCompare) returns 1, while InStr(1,"is","i",vbTextCompare) returns 0.
  • InStr(1,"fœtus","fetus",vbTextCompare) returns 0, while InStr(1,"fœtus","foe",vbTextCompare) returns 1.
  • InStr(1,"Þingvellir","hi",vbTextCompare) returns 1.

Text comparison also affects other functions: InStrB, InStrRev, Replace, Split and StrComp. The effects are not exactly the same across these functions, so be careful. To name an example, in function Replace "Þ" matches "th", but not "t" or "h" alone as with InStr.

Conclusion: vbTextCompare is not an ignore case flag. Avoid text comparison with InStr unless it really is what you want.

Case insensitive search: The safe way

At times we need to search in a case insensitive way. As explained above, there is no safe ignore case flag for InStr. The safest way to call "case insensitive InStr" is to convert both input strings into lower case (or upper case).

position = InStr(LCase$("aVbprogram"), LCase$("VB")) ' Returns 2

Optimization: If one of the strings is already in lower or upper case, it is enough to convert the other.

position = InStr("avbprogram", LCase$("VB"))         ' Returns 2

Further optimization: If you are going to call InStr several times with the same parameter, do your LCase$ first, store the result in a temporary variable and reuse the variable on each call. This way you save the repeated slow call to LCase$

Advanced uses for InStr

That was all about the the basic uses of InStr. Let's get to know what else we can do with it.

Test if character belongs to set

To see whether a character is one of given alternatives, call the following code:

result = InStr("ABC", "A") <> 0

This test tells us if "A" is one of "A", "B" or "C".

Test if string belongs to set

To see whether a longer piece of text is one of given alternatives, call the following kind of code:

result = InStr("-AB-CD-EF-", "-AB-") <> 0

This test tells us if "AB" is one of "AB", "CD" or "EF". Note the use of separators, "-" in this example.

Locate nth occurrence of a string

If you want to find the nth occurrence of a string, not simply the first one, set n to the desired number and run the following code:

position = 0
Do
    position = InStr(position + 1, "avbprogramvb", "vb")
    n = n - 1
Loop Until position = 0 Or n = 0

The loop keeps searching until the nth occurrence is found or there was no match. position tells the result.

To search for the nth occurrence after a certain start position, let position = start - 1.

Search with additional test

To conduct a search with additional conditions, run the following loop:

position = 0
Do
    position = InStr(position + 1, "avbprogram vb", "vb")
    If position = 0 Then Exit Do
Loop Until test(...) = True

Each loop iteration performs a test on each finding. The loop exits when the test condition is met or when there are no (more) matches. The test will typically examine the found position to see whether it contains an acceptable value or not. You can use more complex tests such as the Like operator, tests that you cannot incorporate in the InStr call. In the above example, the test could determine whether "vb" is a word or a part of a longer word.

Optimizing calls to InStr

What comes to pure performance, InStr(,,,vbBinaryCompare) is a quick function. Its counterpart InStr(,,,vbTextCompare) is very slow. It really pays off to use vbBinaryCompare with InStr.

You can use the start parameter to optimize InStr. Use start to skip the beginning of the string when you know the match must be somewhere farther in the string.

For InStr performance details, please read Optimize string handling in VB6, Part II.

InStrRev – Reverse search

InStrRev searches the string in reverse order: from the end to the start. It locates the last occurrence of a string within another.

InStrRev(string1, string2 [, start] [, compare])

Note how the parameters are in a different order than with InStr. Also note that InStrRev does not reverse the input strings: "ABC" does not match "CBA".

InStrRev runs slowly, especially on a long string1. Use InStr when you can. More

InStrB – Byte search

InStrB treats the input and search strings as byte arrays, not as regular strings. As you may know, VB uses Unicode strings. InStrB lets you by-pass Unicode functionality and use byte arrays as if they were strings.

InStrB([start,] string1, string2 [, compare])

Instead of character position, InStrB returns the byte position of string2 in string1. InStrB should not be used for regular string processing. InStrB is relatively fast and it can be used for optimization, but it's tricky. Optimization with InStrB

Make your code shine - with Project Analyzer

Visual Basic InStr
URN:NBN:fi-fe20071012

©Aivosto Oy -