我有一个带2个字符串参数的方法。一个包含普通字符串,另一个包含带有一个或多个通配符的字符串。我尝试过以下代码:
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
我意识到它无法正常工作。如果我将ABCD作为普通字符并将A * CD作为我的通配符字符串,即使我的普通字符串是CDAB,匹配也会起作用,这不是我想要的。
任何想法??
非常感谢。
答案 0 :(得分:8)
你的方法很有意思,但即使纠正过也效率很低。通配符匹配算法的有效实现使用shift-or algorithm的扩展(根据维基百科也被某些来源称为“bitap”,但我自己从未读过它。)
对传统移位或算法的唯一更改是在预处理中:对于您在模式中遇到的每个*
,在此位置启用字母表中的所有字符。< / p>
如果您想更正自己的算法,请将Contains
调用替换为IndexOf
,并提供应开始搜索的位置 - 即上一次匹配后的位置。这适用于大多数情况,但它会执行非贪婪搜索,在某些情况下可能会失败。详尽的搜索必然会回溯。正如我所说,这是低效的,而移位或算法不会受到这个缺点的影响。
但所有这些都是不必要的,因为VB已经提供了必要的操作符: Like
If fullString Like wildcardString Then
' Yep, matches.
End If
关于风格的说明:
在声明变量时始终初始化变量,不要不必要地单独声明和初始化。
即写,
Dim stringParts As String() = wildcardString.Split("*")
' or, with Option Infer On:
Dim stringParts = wildcardString.Split("*")
此外,将布尔值与文字(If X = False
...)进行比较是没有意义的。只需写下
If fullString.Contains(str) Then
答案 1 :(得分:0)
"*"
不代表单个字符,而是代表任何范围的字符。如果您想比较两个字符串,我发现if maskedtextbox1.text like maskedtextbox2.text
或maskedtextbox2.text = maskedtextbox1.text
效果非常好。
答案 2 :(得分:0)
试试这个,这有帮助吗?
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