正则表达式仅返回1个匹配

时间:2017-04-17 18:40:30

标签: regex vba excel-vba excel

我的VBA函数应该使用一个引用一系列单位的字符串(即 "WAL1-5" ),然后返回另一个字符串。

我想接受参数,并将其放在逗号分隔的字符串中, 因此"WAL1-5"应该成为"WAL1, WAL2, WAL3, WAL4, WAL5".

它并不总是一个数字。例如,我可能需要将"DEV11-18"或类似内容分开。

我从来没有使用正则表达式,但是继续尝试不同的东西来使这个工作,它似乎只找到1个匹配而不是3个。

有什么想法吗?这是我的代码:

Private Function split_metergroup(ByVal group As String) As String   
    Dim re As Object
    Dim matches As Object
    Dim result As String
    Dim prefix As String
    Dim startVar As Integer
    Dim endVar As Integer
    Dim i As Integer

    Set re = CreateObject("vbscript.regexp")
    re.Pattern = "([A-Z]+)(\d+)[-](\d+)"
    re.IgnoreCase = False
    Set matches = re.Execute(group)

    Debug.Print matches.Count

    If matches.Count <> 0 Then
        prefix = matches.Item(0)
        startVar = CInt(matches.Item(1)) 'error occurs here
        endVar = CInt(matches.Item(2))
        result = ""

        For i = startVar To endVar - 1
            result = result & prefix & i & ","
        Next i

        split_metergroup = result & prefix & endVar
    Else
        MsgBox "There is an error with splitting a meter group."
        split_metergroup = "ERROR"
    End If

End Function

我尝试设置global = true但我意识到这不是问题所在。错误实际上发生在评论的行上,但我认为它是因为只有1个匹配。

我尝试使用Google搜索,但每个人的情况似乎与我的情况略有不同,因为这是我第一次使用RE,我不认为我理解这些模式足以看出是否可能是问题

谢谢!

3 个答案:

答案 0 :(得分:2)

尝试以下修改后的Function

Private Function split_metergroup(ByVal group As String) As String

    Dim re As Object
    Dim matches As Variant
    Dim result As String
    Dim prefix As String
    Dim startVar As Integer
    Dim endVar As Integer
    Dim i As Integer

    Set re = CreateObject("VBScript.RegExp")
    With re
        .Global = True
        .IgnoreCase = True
        .Pattern = "[0-9]{1,20}" '<-- Modified the Pattern
    End With

    Set matches = re.Execute(group)                  
    If matches.Count > 0 Then
        startVar = CInt(matches.Item(0)) ' <-- modified 
        endVar = CInt(matches.Item(1)) ' <-- modified
        prefix = Left(group, InStr(group, startVar) - 1) ' <-- modified
        result = ""

        For i = startVar To endVar - 1
            result = result & prefix & i & ","
        Next i    
        split_metergroup = result & prefix & endVar
    Else
        MsgBox "There is an error with splitting a meter group."
        split_metergroup = "ERROR"
    End If

End Function

Sub测试了它:

Option Explicit

Sub TestRegEx()

Dim Res As String

Res = split_metergroup("DEV11-18")
Debug.Print Res

End Sub

结果我进入了即时窗口:

DEV11,DEV12,DEV13,DEV14,DEV15,DEV16,DEV17,DEV18

答案 1 :(得分:2)

另一个RegExp选项,此选项使用SubMatches

测试

Sub TestRegEx()
Dim StrTst As String
MsgBox WallIndside("WAL7-21")
End Sub

代码

Function WallIndside(StrIn As String) As String

    Dim objRegex As Object
    Dim objRegMC As Object
    Dim lngCnt As Long

    Set objRegex = CreateObject("VBScript.RegExp")
    With objRegex
        .Global = True
        .IgnoreCase = True
        .Pattern = "([a-z]+)(\d+)-(\d+)"
        If .test(StrIn) Then
            Set objRegMC = .Execute(StrIn)
            For lngCnt = objRegMC(0).submatches(1) To objRegMC(0).submatches(2)
                 WallIndside = WallIndside & (objRegMC(0).submatches(0) & lngCnt & ", ")
            Next
                WallIndside = Left$(WallIndside, Len(WallIndside) - 2)
        Else
            WallIndside = "no match"
        End If
    End With
End Function   

答案 2 :(得分:2)

@Shai Rado的回答奏效了。但我自己想出了为什么我的原始代码无效,并能够轻易修改它。

该模式只找到1个匹配,因为它找到了1个完整匹配。完整匹配是整个字符串。子匹配真的是我想要得到的。请参阅下图,了解我实际获得的匹配。

Matches I was getting

这是我修改的原始代码工作(要求完整匹配的每个子匹配):

How I modified the code