从 VBA 范围内删除特殊字符

Remove special characters from range in VBA

我创建了一个 VBA 代码来删除列中可用的所有特殊字符。例如,我在一列的每个单元格中都有一个字母数字字符和一些特殊字符: 假设在一个单元格中我有一个值:abc@123!-245 执行我的代码后,我得到输出 abc 123 245 在这里,我的代码可以很好地删除所有特殊字符。我的代码如下:

Sub ReplaceSpecial()
    Dim cel As Range
    Dim strVal As String
    Dim i As Long
    Application.ScreenUpdating = False
    For Each cel In Selection
        strVal = cel.Value
        For i = 1 To Len(strVal)
            Select Case Asc(Mid(strVal, i, 1))
                Case 32, 48 To 57, 65 To 90, 97 To 122
                    ' Leave ordinary characters alone
                Case Else
                    Mid(strVal, i, 1) = " "
            End Select
        Next i
        cel.Value = strVal
    Next cel
    Application.ScreenUpdating = True
End Sub

现在,如果我想删除输出的 space,使输出看起来像 abc123245,如何在 VBA 中执行此操作? 输入:abc@123!-245 当前输出:abc 123 245 所需输出:abc123245

您可以只使用允许的字符构造一个新字符串。

Sub ReplaceSpecial()
    Dim cel As Range
    Dim strVal As String, temp As String
    Dim i As Long
    Application.ScreenUpdating = False
    For Each cel In Selection
        strVal = cel.Value
        temp = vbNullString
        For i = 1 To Len(strVal)
            Select Case Asc(Mid(strVal, i, 1))
                Case 32, 48 To 57, 65 To 90, 97 To 122
                    temp = temp & Mid(strVal, i, 1)                   
            End Select
        Next i
        cel.Value = temp
    Next cel
    Application.ScreenUpdating = True
End Sub

如果您想在当前努力的基础上再接再厉,请替换:

cel.Value = strVal

与:

cel.Value = Replace(strVal, " ", "")

考虑:

Sub ReplaceSpecial()
    Dim cel As Range
    Dim strVal As String
    Dim i As Long
    Application.ScreenUpdating = False
    For Each cel In Selection
        strVal = cel.Value
        For i = 1 To Len(strVal)
            Select Case Asc(Mid(strVal, i, 1))
                Case 32, 48 To 57, 65 To 90, 97 To 122
                    ' Leave ordinary characters alone
                Case Else
                    Mid(strVal, i, 1) = " "
            End Select
        Next i
        cel.Value = Replace(strVal, " ", "")
    Next cel
    Application.ScreenUpdating = True
End Sub

使用正则表达式的对象并使用否定字符替换所有不需要的字符class。出于演示目的:

Sub Test()

Dim str As String: str = "abc@123!-245"

With CreateObject("vbscript.regexp")
    .Global = True
    .Pattern = "[^0-9A-Za-z ]"
    str = .Replace(str, "")
End With

Debug.Print str

End Sub

模式 [^0-9A-Za-z ] 是一个否定字符 class 并捕获了所有 不是 字母数字 一个 space 字符。您将在此在线 demo.

中找到更深入的解释

在撰写本文时,我不确定您是否要省略 space 个字符。如果是这样,只需从模式中删除 space。


以为我会使用 Like() 运算符加入另一个替代方案:

For i = Len(str) To 1 Step -1
    If Mid(str, i, 1) Like "[!0-9A-Za-z ]" Then
        str= Application.Replace(str, i, 1, "")
    End If
Next

或者使用第二个字符串类型变量(根据@BigBen 的回答):

For i = 1 to Len(str)
    If Mid(str, i, 1) Like "[0-9A-Za-z ]" Then
        temp = temp & Mid(str, i, 1)
    End If
Next

我这么晚 post 的唯一目的是

  • testApplication.Match() 函数的一些特性(将字符串输入与有效字符进行比较)和 to
  • 演示一种将字符串“拆分”为单个字符的好方法,作为 替代方案 并且可能具有指导意义的解决方案(请参阅帮助功能 String2Arr())。

打算,但是要在这里显示更好或更快的代码。

Application.Match() 不仅允许在数组中执行 1 个字符搜索,而且可以一次性比较两个数组, 即针对有效字符数组(空白、所有数字和从 A 到 Z 的字符)的字符数组(基于原子化字符串输入)。 由于 Application.Match 不区分大小写,因此可以使用例如小写字符。

输入字符的所有发现 return 它们在有效字符数组中的位置(否则会导致错误 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()

Returns 在有效字符数组中找到的字符位置数组:

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: 
    s = StrConv(s, vbUnicode)
    String2Arr = Split(s, vbNullChar, Len(s) \ 2)
End Function