代码之家  ›  专栏  ›  技术社区  ›  Shai Rado

Excel vba regex,从范围内的价格值中提取数字(有逗号,$和-)

  •  1
  • Shai Rado  · 技术社区  · 6 年前

    我从数据库中提取了一个字段数据,它代表一系列值,但它以字符串格式出现在Excel中。 $86,000 - $162,000 .

    我需要从每个单元格中提取最小值和最大值,所以我需要提取其中的数字部分,并忽略 $ , - 以及 , .

    我附上了我所拥有的数据的图像,以及我想要从中提取的值。

    enter image description here

    这是我最接近的模式 正则表达式 但我不是在找什么。

    Pattern = (\d+)(?:\.(\d{1,2}))?

    有人能帮忙吗?

    5 回复  |  直到 6 年前
        1
  •  3
  •   MacroMarc    6 年前

    只是想知道为什么是regex?

    Function GetParts(priceRange As String) As Double()
        Dim arr() As String
        Dim parts() As Double
    
        If InStr(1, priceRange, "-") > 0 Then
            arr = Split(priceRange, "-")
            ReDim parts(0 To UBound(arr))
    
            Dim i As Long
            For i = 0 To UBound(arr)
                parts(i) = CDbl(Replace$(Replace$(Trim$(arr(i)), "$", ""), ",", ""))
            Next i
        End If
        GetParts = parts
    End Function
    
    Sub test()
     MsgBox GetParts("$14,000 - $1,234,567")(0)   'Minimum
    End Sub
    

    编辑

    但是,您可以使用regex将数据字符串匹配到各个部分:

    Function GetPartsRegEx(priceRange As String) As Variant
        Dim arr() As Double
    
        Dim pricePattern As String
        pricePattern = "(\$?\d+[\,\.\d]*)"
    
        'START EDIT 
        Static re As RegExp
        If re Is Nothing Then
            Set re = New RegExp
            re.IgnoreCase = True
            re.Global = True
            re.Pattern = pricePattern & "\s*[\-]\s*" & pricePattern   'look for the pattern first
        End If
    
        Static nums As RegExp
        If nums Is Nothing Then
            Set nums = New RegExp
            'to remove all non digits, except decimal point in case you have pennies
            nums.Pattern = "[^0-9.]"    
            nums.Global = True
        End If
        'END EDIT
    
        If re.test(priceRange) Then
            ReDim arr(0 To 1)   ' fill return array
            arr(0) = CDbl(nums.Replace(re.Replace(priceRange, "$1"), ""))
            arr(1) = CDbl(nums.Replace(re.Replace(priceRange, "$2"), ""))
        Else
            'do some error handling here
            Exit Function
        End If  'maybe throw error if no +ve test or
    
        GetPartsRegEx = arr
    End Function
    
    Sub test()
        MsgBox GetPartsRegEx("$1,005.45 - $1,234,567.88")(1)
    End Sub
    
        2
  •  2
  •   0m3r    6 年前

    下面是一个简单的示例演示 https://regex101.com/r/RTNlVF/1

    Pattern "^\$(\d+\,\d+)\s\-\s\$(\d+\,\d+)"
    

    enter image description here

    Option Explicit
    Private Sub Example()
        Dim RegExp As New RegExp
        Dim Pattern As String
        Dim CelValue As String
        Dim rng As Range
        Dim Cel As Range
    
        Set rng = ActiveWorkbook.Sheets("Sheet1" _
                                ).Range("A2", Range("A9999" _
                                ).End(xlUp))
    
        For Each Cel In rng
            DoEvents
            Pattern = "^\$(\d+\,\d+)\s\-\s\$(\d+\,\d+)"
    
            If Pattern <> "" Then
                With RegExp
                    .Global = True
                    .MultiLine = True
                    .IgnoreCase = False
                    .Pattern = Pattern
                End With
    
                If RegExp.Test(Cel.Value) Then
    '                Debug.Print Cel.Value
    
                    Debug.Print RegExp.Replace(CStr(Cel), "$1")
                    Debug.Print RegExp.Replace(CStr(Cel), "$2")
    
                End If
            End If
        Next
    End Sub
    

    enter image description here enter image description here

        3
  •  1
  •   pnuts    6 年前

    没有循环(但仍然没有regex):

    Sub Split()
        With Columns("B:B")
            .Replace What:="$", Replacement:=""
            Application.CutCopyMode = False
            .TextToColumns Destination:=Range("B1"), DataType:=xlDelimited, Other:=True, OtherChar:="-", FieldInfo:=Array(Array(1, 1), Array(2, 1))
        End With
        Columns("B:C").Insert Shift:=xlToRight
        Columns("D:E").NumberFormat = "0"
        Range("D1").FormulaR1C1 = "Min Value"
        Range("E1").FormulaR1C1 = "Max Value"
        With Range("D1:E1").Interior
            .Pattern = xlSolid
            .PatternColorIndex = xlAutomatic
            .Color = 12611584
        End With
        With Range("D1:E1").Font
            .ThemeColor = xlThemeColorDark1
            .TintAndShade = 0
        End With
    End Sub
    
        4
  •  0
  •   Ferd jmeloc    6 年前

    我做了这个功能:

    Function

    希望它有帮助。 代码:

    Function ExtractNumber(ByVal TextInput As String, _
    Optional ByVal Position As Byte = 0, _
    Optional ByVal Delimiter As String = "-") As Variant
    '   You can use this function in a subprocess that
    '   writes the values in the cells you want, or
    '   you can use it directly in the ouput cells
    
    '   Variables
        Dim RemoveItems(2) As String
        Dim Aux As Variant
    
    '   The variable RemoveItems is an array
    '   containing the characters you want to remove
        RemoveItems(0) = "."
        RemoveItems(1) = ","
        RemoveItems(2) = " "
    
    '   STEP 1 - The variable Aux will store the text
    '   given as input
        Aux = TextInput
    
    '   STEP 2 - Characters stored in the variable
    '   RemoveItems will be removed from Aux
        For i = 0 To UBound(RemoveItems)
    
            Aux = Replace(Aux, RemoveItems(i), "")
    
        Next i
    
    '   STEP 3 - Once Aux is "clean", it will be
    '   transformed into an array containing the
    '   values separated by the delimiter
    
    '   As you can see at the function's header,
    '   Delimiter default value is "-". You can change
    '   it depending on the situation
        Aux = Split(Aux, Delimiter)
    
    '   STEP 4 - The result of this function will be
    '   a numeric value. So, if the value of the
    '   selected position in Aux is not numeric it will
    '   remove the first character assuming it is a
    '   currency symbol.
    
    '   If something fails in the process the function
    '   will return "ERROR", so you can know you may
    '   verify the inputs or adjust this code for
    '   your needs.
    
    On Error GoTo ErrHndl
    
        If Not IsNumeric(Aux(Position)) Then
    
            ExtractNumber = CLng(Mid(Aux(Position), 2))
    
        Else
    
            ExtractNumber = CLng(Aux(Position))
    
        End If
    
        Exit Function
    
    ErrHndl:
    
        ExtractNumber = "ERROR"
    
    End Function
    
        5
  •  0
  •   Ron Rosenfeld    6 年前

    您甚至可以只使用工作表公式。在某些情况下,Excel将忽略 $ , . Double一元将返回的字符串转换为数值。

    First Value:  =--LEFT(A1,FIND("-",A1)-1)
    Second Value: =--MID(A1,FIND("-",A1)+1,99)