我写这篇迟到的帖子的唯一目的是
- 测试►<code>Application.Match() 函数的一些特性(将字符串输入与有效字符进行比较)并
- 演示一种将字符串“拆分”为单个字符的好方法,作为替代且可能具有指导意义的解决方案(请参阅帮助功能
String2Arr()
)。
但是,我不打算在这里展示更好或更快的代码。
Application.Match()
不仅允许在一个数组中执行 1 个字符搜索,还可以一次比较两个数组,即一个字符数组(基于原子化字符串输入)与一个有效字符数组(空格、所有数字和字符从 A 到Z)。由于Application.Match
不区分大小写,因此采用例如小写字符就足够了。
输入字符的所有结果都会返回它们在有效字符数组中的位置(否则会导致错误 2042)。此外,有必要排除通配符“*”和“?”,否则它们将被视为发现。
Function ValidChars(ByVal s, Optional JoinResult As Boolean = True)
'Purp: return only valid characters if space,digits,"A-Z" or "a-z"
'compare all string characters against valid characters
Dim tmp: tmp = foundCharAt(s) ' get array with found positions in chars
'overwrite tmp array
Dim i As Long, ii As Long
For i = 1 To UBound(tmp)
If IsNumeric(tmp(i)) Then ' found in valid positions
If Not Mid(s, i, 1) Like "[?*]" Then ' exclude wild cards
ii = ii + 1
tmp(ii) = Mid(s, i, 1) ' get char from original string
End If
End If
Next
ReDim Preserve tmp(1 To ii) ' reduce to new size
'join tmp elements to resulting string (if argument JoinResult = True)
ValidChars = IIf(JoinResult, Join(tmp, ""), tmp)
End Function
帮助功能foundCharAt()
返回有效字符数组中找到的字符位置数组:
Function foundCharAt(ByVal s As String) As Variant
'Purp: return array of found character positions in chars string
'Note: (non-findings show Error 2042; can be identified by IsError + Not IsNumeric)
Dim chars: chars = String2Arr(" 0123456789abcdefghijklmnopqrstuvwxyz")
foundCharAt = Application.Match(String2Arr(s), chars, 0)
End Function
帮助功能String2Arr()
在原子化字符串输入后分配单个字符数组:
Function String2Arr(ByVal s As String) As Variant
'Purp: return array of all single characters in a string
'Idea: https://stackoverflow.com/questions/13195583/split-string-into-array-of-characters
s = StrConv(s, vbUnicode)
String2Arr = Split(s, vbNullChar, Len(s) \ 2)
End Function