Related articlesOptimize string handling in VB6, Part I
Optimize string handling in VB6, Part II
VB6 statements and constants in this article:
InStr, InStrB, InStrRev, Option Compare, vbBinaryCompare, vbTextCompare.
InStr returns the first occurrence of a string inside another string.
InStr([start,] string1, string2 [, compare])
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.
Nullif either string1 or string2 is
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.
In the following examples we assume that
Option Compare Binary is in effect. This is the default setting.
' Returns 2 position = InStr("avbprogram", "vb") ' Also returns 2 position = InStr("avbprogramvb", "vb")
' Returns 2 position = InStr("avbprogram", "v")
The start parameter is useful to skip the start of the string. This allows us to skip known instances of the search string.
' Returns 11 position = InStr(4, "avbprogramvb", "vb")
It is also useful for optimizing calls to InStr. If we can start in the middle, the search will perform faster.
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
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
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, "Straße", "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.
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.
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.
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.
InStr(1, "Ætna", "et", vbTextCompare)returns 1. Note how the match happens "in the middle" of the AE ligature.
InStr(1, "Fjærland", "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, "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:
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.
vbTextCompare is not an ignore case flag.
Avoid text comparison with InStr unless it really is what you want.
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).
' Returns 2 position = InStr(LCase$("aVbprogram"), LCase$("VB"))
Optimization: If one of the strings is already in lower or upper case, it is enough to convert the other.
' Returns 2 position = InStr("avbprogram", LCase$("VB"))
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$
That was all about the the basic uses of InStr. Let's get to know what else we can do with it.
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".
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.
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, change the first line to
position = start - 1.
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.
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 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 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
Visual Basic InStr