Extracting digits from a cell with varying char length

时光总嘲笑我的痴心妄想 提交于 2021-02-16 20:06:35

问题


I have a group of cells, the first of the string never changes, it is and always will (until the coder changes it) 20 characters (inc spaces).

I then want to extract the 3 numbers (and in some cases 2) from the remaining sequence.

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.

In the sample above you can see that there is no set value after the first 20 chars.

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

I can't get a sequence that gets all the cells correct, I've tried the following:

=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

If I & the cells as part of the calculation, they then don't calculate in the next mathematical step as I've had to allow for spaces in my code, in the case that there may be 2 digit numbers, not single.

=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

What I need to end up with is:

2140  
19440  
175  
840  
1  
999999   

Many thanks in advance.


回答1:


When it comes to pattern matching in strings, RegEx if often the way to go.

In Excel, this requires a VBA solution, using a reference to "Microsoft VBScript Regular Expresions 5.5" (you can go late bound if you prefer)

Here's a starter for your case, as a UDF

Use it as a formula like =GetValues(A1) assuming 1st raw data is in A1. Copy down for as many rows as required

This will extract up to 3 values from a string.

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:


This formula worked for me with your data, assuming text string in cell 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,"")

I assume you don't want the value for "Gold"?




回答3:


Since you are just stripping digits you can use a short one-shot RegExp if you wanted the VBA route:

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



回答4:


Here's another method, using worksheet formulas, for returning all of the digits in a string. Harlan Grove put it out there many years ago.

First define a Name (with Workbook scope):

Seq Refers to: =ROW(INDEX($1:$65536,1,1):INDEX($1:$65536,255,1))

Then, assuming your string is in A1, use the following array-entered formula. (Formula is entered by holding down ctrl+shift while hitting Enter. (If you do this correctly, Excel will place braces {...} around the formula.

=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)))))


来源:https://stackoverflow.com/questions/28523745/extracting-digits-from-a-cell-with-varying-char-length

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!