【发布时间】:2011-11-06 13:09:41
【问题描述】:
我需要从string 中查找号码。如何在 VBA Excel 中从string 中找到数字?
【问题讨论】:
我需要从string 中查找号码。如何在 VBA Excel 中从string 中找到数字?
【问题讨论】:
假设你的意思是你想去掉非数字,你应该能够使用类似的东西:
Function onlyDigits(s As String) As String
' Variables needed (remember to use "option explicit"). '
Dim retval As String ' This is the return string. '
Dim i As Integer ' Counter for character position. '
' Initialise return string to empty '
retval = ""
' For every character in input string, copy digits to '
' return string. '
For i = 1 To Len(s)
If Mid(s, i, 1) >= "0" And Mid(s, i, 1) <= "9" Then
retval = retval + Mid(s, i, 1)
End If
Next
' Then return the return string. '
onlyDigits = retval
End Function
调用它:
Dim myStr as String
myStr = onlyDigits ("3d1fgd4g1dg5d9gdg")
MsgBox (myStr)
会给你一个对话框,其中包含:
314159
前两行显示了如何将它存储到任意字符串变量中,随心所欲。
【讨论】:
pi、e、xyzzy、plugh、42 和其他“神奇”项目 :-)
正则表达式是用来解析的。虽然语法可能需要一段时间才能掌握,但这种方法非常有效,并且对于处理更复杂的字符串提取/替换非常灵活
Sub Tester()
MsgBox CleanString("3d1fgd4g1dg5d9gdg")
End Sub
Function CleanString(strIn As String) As String
Dim objRegex
Set objRegex = CreateObject("vbscript.regexp")
With objRegex
.Global = True
.Pattern = "[^\d]+"
CleanString = .Replace(strIn, vbNullString)
End With
End Function
【讨论】:
+1 使用 regex,我很高兴我们可以在 VBA 中使用它,它为 VBA 的 coolness >dimdim照明文化 =)
扩展 brettdj 的答案,以便将不相交的嵌入数字解析为单独的数字:
Sub TestNumList()
Dim NumList As Variant 'Array
NumList = GetNums("34d1fgd43g1 dg5d999gdg2076")
Dim i As Integer
For i = LBound(NumList) To UBound(NumList)
MsgBox i + 1 & ": " & NumList(i)
Next i
End Sub
Function GetNums(ByVal strIn As String) As Variant 'Array of numeric strings
Dim RegExpObj As Object
Dim NumStr As String
Set RegExpObj = CreateObject("vbscript.regexp")
With RegExpObj
.Global = True
.Pattern = "[^\d]+"
NumStr = .Replace(strIn, " ")
End With
GetNums = Split(Trim(NumStr), " ")
End Function
【讨论】:
如果数字在字符串的前端,则使用内置的 VBA 函数 Val:
Dim str as String
Dim lng as Long
str = "1 149 xyz"
lng = Val(str)
lng = 1149
【讨论】:
Val 做了一些非常奇怪的事情:Val("3d1fgd4g1dg5d9gdg") 返回30,而Va("3d11gd4g1dg5d9gdg") 返回300000000000。
Val("3d1") 和 Val("3d11") 分别返回 30 和 300000000000。
这是 brettdj 和 pstraton 帖子的变体。
这将返回一个真值并且不会给您#NUM! 错误。 \D 是除数字以外的任何东西的简写。其余部分与其他部分非常相似,只是进行了这个小修复。
Function StripChar(Txt As String) As Variant
With CreateObject("VBScript.RegExp")
.Global = True
.Pattern = "\D"
StripChar = Val(.Replace(Txt, " "))
End With
End Function
【讨论】:
这是基于another answer,但只是重新格式化:
假设你的意思是你想去掉非数字,你应该能够使用类似的东西:
'
' Skips all characters in the input string except digits
'
Function GetDigits(ByVal s As String) As String
Dim char As String
Dim i As Integer
GetDigits = ""
For i = 1 To Len(s)
char = Mid(s, i, 1)
If char >= "0" And char <= "9" Then
GetDigits = GetDigits + char
End If
Next i
End Function
调用它:
Dim myStr as String
myStr = GetDigits("3d1fgd4g1dg5d9gdg")
Call MsgBox(myStr)
会给你一个对话框,其中包含:
314159
前两行显示了如何将它存储到任意字符串变量中,随心所欲。
【讨论】:
我一直在寻找相同问题的答案,但有一段时间我找到了自己的解决方案,我想将其分享给将来需要这些代码的其他人。这是另一个没有功能的解决方案。
Dim control As Boolean
Dim controlval As String
Dim resultval As String
Dim i as Integer
controlval = "A1B2C3D4"
For i = 1 To Len(controlval)
control = IsNumeric(Mid(controlval, i, 1))
If control = True Then resultval = resultval & Mid(controlval, i, 1)
Next i
结果 = 1234
【讨论】:
通过Byte数组替代
如果您将字符串分配给Byte 数组,您通常会获得数组元素对中每个字符的等效数字。通过Like 运算符使用循环进行数字检查,并将连接的数组作为字符串返回:
Function Nums(s$)
Dim by() As Byte, i&, ii&
by = s: ReDim tmp(UBound(by)) ' assign string to byte array; prepare temp array
For i = 0 To UBound(by) - 1 Step 2 ' check num value in byte array (0, 2, 4 ... n-1)
If Chr(by(i)) Like "#" Then tmp(ii) = Chr(by(i)): ii = ii + 1
Next i
Nums = Trim(Join(tmp, vbNullString)) ' return string with numbers only
End Function
调用示例
Sub testByteApproach()
Dim s$: s = "a12bx99y /\:3,14159" ' [1] define original string
Debug.Print s & " => " & Nums(s) ' [2] display original string and result
End Sub
将在即时窗口中显示原始字符串和结果字符串:
a12bx99y /\:3,14159 => 1299314159
【讨论】:
基于@brettdj 的回答,使用带有两个修改的 VBScript 正则表达式 ojbect:
Function GetDigitsInVariant(inputVariant As Variant) As Variant
' Returns:
' Only the digits found in a varaint.
' Examples:
' GetDigitsInVariant(Null) => Null
' GetDigitsInVariant("") => ""
' GetDigitsInVariant(2021-/05-May/-18, Tue) => 20210518
' GetDigitsInVariant(2021-05-18) => 20210518
' Notes:
' If the inputVariant is null, null will be returned.
' If the inputVariant is "", "" will be returned.
' Usage:
' VBA IDE Menu > Tools > References ...
' > "Microsoft VBScript Regular Expressions 5.5" > [OK]
' With an explicit object reference to RegExp we can get intellisense
' and review the object heirarchy with the object browser
' (VBA IDE Menu > View > Object Browser).
Dim regex As VBScript_RegExp_55.RegExp
Set regex = New VBScript_RegExp_55.RegExp
Dim result As Variant
result = Null
If IsNull(inputVariant) Then
result = Null
Else
With regex
.Global = True
.Pattern = "[^\d]+"
result = .Replace(inputVariant, vbNullString)
End With
End If
GetDigitsInVariant = result
End Function
测试:
Private Sub TestGetDigitsInVariant()
Dim dateVariants As Variant
dateVariants = Array(Null, "", "2021-/05-May/-18, Tue", _
"2021-05-18", "18/05/2021", "3434 ..,sdf,sfd 444")
Dim dateVariant As Variant
For Each dateVariant In dateVariants
Debug.Print dateVariant & ": ", , GetDigitsInVariant(dateVariant)
Next dateVariant
Debug.Print
End Sub
【讨论】:
Public Function ExtractChars(strRef$) As String
'Extract characters from a string according to a range of charactors e.g'+.-1234567890'
Dim strA$, e%, strExt$, strCnd$: strExt = "": strCnd = "+.-1234567890"
For e = 1 To Len(strRef): strA = Mid(strRef, e, 1)
If InStr(1, strCnd, strA) > 0 Then strExt = strExt & strA
Next e: ExtractChars = strExt
End Function
在即时调试对话框中:
? ExtractChars("a-5d31.78K")
-531.78
【讨论】: