4

I have a method that takes 2 string arguments. One that contains a normal string and one that contains a string with one or more wildcard characters. I've tried the following code:

Private Function DoesMatchWildcardString(ByVal fullString As String, ByVal wildcardString As String) As Boolean Dim stringParts() As String Dim matches As Boolean = True stringParts = wildcardString.Split("*") For Each str As String In stringParts If fullString.Contains(str) = False Then matches = False End If Next Return matches End Function 

The I realized that it won't work properly. If I have ABCD as a normal and A*CD as my wildcard string the match will work even if my normal string was CDAB, which is not what I want.

Any ideas??

Thanks a lot.

5
  • What are possible wildcard characters? Are you talking about just *, or more full regex-like *, +, ?, ., etc. ? Commented May 16, 2012 at 20:10
  • Right now I'm only working with * Commented May 16, 2012 at 20:10
  • Why don't you test each part of the string one at a time? So split the wildcard string A*CD into two. Test A against the first character of the normal string. Then test CD against the third and fourth characters of the normal string. Commented May 16, 2012 at 20:12
  • In your example, it seems that * stands for a single character e.g. A*CD - is that true? Commented May 16, 2012 at 20:14
  • @kaveman - No the * can stand for any number of characters. Commented May 16, 2012 at 20:22

3 Answers 3

9

Your approach is interesting but very inefficient even once corrected. An efficient implementation of the wildcard matching algorithm uses an extension of the shift-or algorithm (according to Wikipedia also called “bitap” by some sources, but I’ve never read that myself).

The only change to the conventional shift-or algorithm is in the preprocessing: For each * that you encounter in the pattern, enable all characters in the alphabet at this position.

If you want to correct your own algorithm, then replace the Contains call by IndexOf, and supply the position where it should start searching – namely, after the previous match. This will work for most cases, but it will perform a non-greedy search which might fail in some circumstances. An exhaustive search will necessarily backtrack. As I said, that’s inefficient, and the shift-or algorithm doesn’t suffer from this shortcoming.

But all of this is unnecessary since VB already provides the necessary operator: Like

If fullString Like wildcardString Then ' Yep, matches. End If 

A note on style:

Always initialise variables when you declare them, do not separate declaration and initialisation needlessly.

That is, write

Dim stringParts As String() = wildcardString.Split("*") ' or, with Option Infer On: Dim stringParts = wildcardString.Split("*") 

Furthermore, it makes no sense to compare a Boolean with a literal (If X = False …). Just write

If fullString.Contains(str) Then 
Sign up to request clarification or add additional context in comments.

1 Comment

I like the style tips. I would add that if all you are doing in a Boolean test is determining which value to set a different Boolean variable, combine them into one e.g. matches = fullString.Contains(str)
0

"*" does not represent a single char but any range of chars. When you want to compare two strings I have found that the if maskedtextbox1.text like maskedtextbox2.text or maskedtextbox2.text = maskedtextbox1.text works pretty well.

Comments

0

Try this, does this help?

Private Function DoesMatchWildcardString(ByVal fullString As String, ByVal wildcardString As String) As Boolean Dim count As Integer = 1 Dim wildchr As String Dim fschr As String Dim resultstring As String = String.Empty Do Until count - 1 = Len(wildcardString) wildchr = Mid$(wildcardString, count, 1) fschr = Mid$(fullString, count, 1) If wildchr = "*" Then ' this one matches any char resultstring = resultstring & fschr Else If wildchr = fschr Then resultstring = resultstring & fschr End If End If count = count + 1 Loop Return resultstring = fullString End Function 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.