从具有不同字符长度的单元格中提取数字

问题描述 投票:0回答:4

我有一组单元格,字符串的第一个永远不会改变,它永远不会改变(直到编码器改变它)

20
字符(包括空格)。

然后我想从剩余序列中提取 3 个数字(在某些情况下是 2 个)。

The monthly cost is 2 silver, 1 copper and 40 iron.
The monthly cost is 1 silver, 94 copper and 40 iron.
The monthly cost is 1 silver and 75 copper.
The monthly cost is 8 silver and 40 copper.
The monthly cost is 1 silver.
The monthly cost is 99 silver, 99 copper and 99 iron.
The monthly cost is 1 gold.

在上面的示例中,您可以看到前 20 个字符之后没有设置值。

1 or 99 silver 
1 or 99 copper
0, 1 or 99 iron  

我无法获得使所有单元格正确的序列,我尝试了以下方法:

=IF(J7<>1,(MID(TRIM(J7),FIND(" iron",TRIM(J7))-2,FIND(" iron",TRIM(J7))-FIND(" iron",TRIM(J7))+3)),"")    
results in:  #VALUE!  (when no iron)  

=TRIM(MID(J6,FIND(" silver",J6)-2,LEN(J6)-FIND(" silver",J6)-26))&TRIM(MID(J6,FIND(" copper",J6)-2,LEN(J6)-FIND(" copper",J6)-16))&TRIM(MID(J6,FIND(" iron",J6)-2,LEN(J6)-FIND(" iron",J6)-3))  
results in:  1 s9440   

=MID(J7,31,2-ISERR(MID(J7,21,1)+0))  
results in:  nd

如果我

&
将单元格作为计算的一部分,那么它们就不会在下一个数学步骤中进行计算,因为在可能有 2 位数字的情况下,我必须在代码中考虑
spaces
,不是单身。

=MID(J5,SEARCH(" silver",J5,1)-2,2)&MID(J5,SEARCH(" copper",J5,1)-2,2)&MID(J5,SEARCH(" iron",J5,1)-2,2)  
results:   2 140
not:       2140

我最终需要的是:

2140  
19440  
175  
840  
1  
999999   

提前非常感谢。

excel excel-formula excel-2010 vba
4个回答
5
投票

这个公式对我来说适用于你的数据,假设单元格 A1 中是文本字符串

=IFERROR(MID(A1,SEARCH("silver",A1)-3,2)+0,"")&IFERROR(MID(A1,SEARCH("copper",A1)-3,2)+0,"")&IFERROR(MID(A1,SEARCH("iron",A1)-3,2)+0,"")

我想你不想要“黄金”的价值?


2
投票

当涉及到字符串中的模式匹配时,RegEx 通常是最佳选择。

在 Excel 中,这需要 VBA 解决方案,使用对“Microsoft VBScript 正则表达式 5.5”的引用(如果您愿意,可以后期绑定)

这是您作为 UDF 的案例的开端

将其用作类似于

=GetValues(A1)
的公式,假设第一个原始数据位于
A1
中。 根据需要向下复制尽可能多的行

这将从字符串中提取最多 3 个值。

Function GetValues(r As Range) As Variant
    Dim re As RegExp
    Dim m As MatchCollection
    Dim v As Variant
    Dim i As Long
    Set re = New RegExp

    re.Pattern = "(\d+)\D+(\d+)\D+(\d+)"
    If re.test(r.Value) Then
        Set m = re.Execute(r.Value)
    Else
        re.Pattern = "(\d+)\D+(\d+)"
        If re.test(r.Value) Then
            Set m = re.Execute(r.Value)
        Else
            re.Pattern = "(\d+)"
            If re.test(r.Value) Then
                Set m = re.Execute(r.Value)
            End If
        End If
    End If
    If m Is Nothing Then
        GetValues = vbNullString
    Else
        For i = 0 To m.Item(0).SubMatches.Count - 1
            v = v & m.Item(0).SubMatches(i)
        Next
        GetValues = v
    End If
End Function

2
投票

由于您只是剥离数字,因此如果您想要 VBA 路线,您可以使用短的一次性

RegExp

Function GetDigits(strIn As String) As String
Dim objRegex As Object
Set objRegex = CreateObject("vbscript.regexp")
With objRegex
    .Pattern = "[^\d]+"
    .Global = True
    GetDigits = .Replace(strIn, vbNullString)
End With
End Function

1
投票

这是另一种方法,使用工作表公式返回字符串中的所有数字。 Harlan Grove 多年前就已经把它放在那里了。

首先定义一个名称(具有工作簿范围):

序列 参考:

=ROW(INDEX($1:$65536,1,1):INDEX($1:$65536,255,1))

然后,假设您的字符串位于 A1 中,请使用以下数组输入公式。 (按下 ctrl+shift 并按 Enter 即可输入公式。(如果操作正确,Excel 会在公式周围放置大括号

{...}

=SUM(IF(ISNUMBER(1/(MID(A1,Seq,1)+1)),MID(A1,Seq,1)*10^MMULT(-(Seq<TRANSPOSE(Seq)),-ISNUMBER(1/(MID(A1,Seq,1)+1)))))
© www.soinside.com 2019 - 2024. All rights reserved.