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

Extracting digits from a cell with varying char length

我有一组单元格,字符串的第一个永远不会改变,它永远是(直到编码器改变它)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

如果我 & 单元格作为计算的一部分,那么它们不会在下一个数学步骤中计算,因为我必须在我的代码中允许 spaces,在情况下可能有2位数字,而不是单个数字。

=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   

非常感谢。

当谈到字符串中的模式匹配时,RegEx 通常是首选。

在 Excel 中,这需要一个 VBA 解决方案,使用对 "Microsoft VBScript Regular Expresions 5.5" 的引用(如果您愿意,可以延迟绑定)

这是您案例的开始,作为 UDF

假设第一个原始数据在 A1 中,将其用作类似 =GetValues(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

这个公式对我适用于你的数据,假设单元格 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,"")

我假设您不想要 "Gold" 的值?

因为你只是剥离数字,如果你想要 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

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

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

顺序 参考:=ROW(INDEX($1:$65536,1,1):INDEX($1:$65536,255,1))

然后,假设您的字符串在 A1 中,使用以下 array-entered 公式。 (通过按住 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)))))