Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String 如何从字符串中查找数字?_String_Vba_Excel - Fatal编程技术网

String 如何从字符串中查找数字?

String 如何从字符串中查找数字?,string,vba,excel,String,Vba,Excel,我需要从字符串中查找数字。如何从VBA Excel中的字符串中查找数字?如果您的意思是要删除非数字,您应该能够使用以下方法: 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 Int

我需要从
字符串中查找数字。如何从VBA Excel中的
字符串中查找数字?

如果您的意思是要删除非数字,您应该能够使用以下方法:

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
将显示一个对话框,其中包含:

314159
314159

前两行显示了如何将其存储到任意字符串变量中,可以根据需要进行处理。

正则表达式是为解析而构建的。虽然语法可能需要一段时间才能掌握,但这种方法非常有效,并且对于处理更复杂的字符串提取/替换非常灵活

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

扩展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)
液化天然气=1149


这是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
这是基于,但只是重新格式化:


假设您的意思是希望去掉非数字,那么您应该能够使用以下内容:

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
'
'跳过输入字符串中除数字以外的所有字符
'
函数GetDigits(ByVal s作为字符串)作为字符串
Dim char作为字符串
作为整数的Dim i
GetDigits=“”
对于i=1到Len(s)
char=Mid(s,i,1)

如果char>=“0”和char我一直在寻找同一个问题的答案,但有一段时间我找到了自己的解决方案,我想与将来需要这些代码的其他人分享。这里是另一个没有函数的解决方案

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

resultval=1234

通过
字节
数组替代

如果将字符串分配给
字节
数组,则通常会获得成对数组元素中每个字符的等效数字。通过
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
将在即时窗口中显示原始字符串和结果字符串:


基于@brettdj使用VBScript regex-ojbect的答案,有两个修改:

  • 函数处理变量并返回变量。也就是说,处理一个无效的案例;及
  • 使用显式对象创建,并参考“Microsoft VBScript正则表达式5.5”库
函数GetDigitsInVariant(inputVariant作为Variant)作为Variant
“返回:
“只有在varaint中找到的数字。
例如:
'GetDigitsInVariant(Null)=>Null
'GetDigitsInVariant(“”=>“”
“GetDigits不变量(2021年5月5日至18日,星期二)=>20210518
'GetDigits不变量(2021-05-18)=>20210518
'注:
'如果inputVariant为null,则返回null。
如果inputVariant为“”,则将返回“”。
'用法:
'VBA IDE菜单>工具>参考。。。
'>“Microsoft VBScript正则表达式5.5”>[确定]
'通过对RegExp的显式对象引用,我们可以获得intellisense
'并使用对象浏览器查看对象继承人权限
'(VBA IDE菜单>视图>对象浏览器)。
将正则表达式设置为VBScript\u RegExp\u 55.RegExp
Set regex=New VBScript\u RegExp\u 55.RegExp
作为变量的模糊结果
结果=空
如果为空(inputVariant),则
结果=空
其他的
用正则表达式
.Global=True
.Pattern=“[^\d]+”
结果=.Replace(inputVariant,vbNullString)
以
如果结束
GetDigits不变量=结果
端函数
测试:

Private子testGetDigits不变量()
将变量视为变量
dateVariants=Array(空,“,”2021-/05 May/-18,星期二“_
“2021-05-18”、“2021年5月18日”、“3434..,sdf,sfd 444”)
作为变量的变量
对于dateVariants中的每个dateVariant
Debug.Print dateVariant&“:”,getDigits不变量(dateVariant)
下一个日期变量
调试。打印
端接头

谢谢,它很管用。抱歉,我问了一个非常基本的问题,我想使用这个“onlydigits”值输入另一个方法。没问题,@user905527,我已经在最后更新了示例代码,以显示如何将其放入变量并传递给另一个函数。您可以减少与IsNumeric函数的比较次数。如果是数字(中间(s,i,1)),那么π的i位是共相关的吗?@ArulxZ,巧合,否。我倾向于使用
Pi
e
xyzy
plugh
42
和其他“神奇”项目来使用
regex
,我很高兴我们可以在VBA中使用它,它为VBA的
dim
dim
lighting culture=)增加了一些酷感,而regex是最优雅的,regex是否会引起大规模的性能冲击?@DarylBennett问得好。实例化对象可能会导致命中率相当于或比循环更差。但是如果对象被实例化一次(比如在数组循环中)并重复运行,它将非常高效?诚然,这个问题是用Excel托管的VBA来表达的,但大多数信息同样适用于任何VBA主机。太棒了,我总是错过VBA中的正则表达式!另请参见:.
Val
做了一些非常奇怪的事情:
Val(“3d1fgd4g1dg5d9gdg”)
返回
30
,而
Va(“3d11gd4g1dg5d9gdg”)
返回
300000000
@zev spitz注意到:非常奇怪的行为。我看到上面例子中的异常结果是分别触发的,但是前三个或四个字符;因此
Val(“3d1”)
Val(“3d11”)
分别返回30和300000000。解释为浮点值(我不知道为什么):3d1=3*10^1;3d11=3*10^11。不要使用Val()!
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