从 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 的唯一目的是
- test ►
Application.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
我创建了一个 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 的唯一目的是
- test ►
Application.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