0

There are a plethora of questions about lookbehinds in VBA. The problem is that, while there are positive and negative lookaheads, VBA doesn't support lookbehinds at all.

Most of the questions people have asked seek to solve a very specific problem of extracting strings from text and the Stack Overflow community has been very helpful in providing workarounds for these particular cases. My question is, could you write a function in VB that simulates positive lookbehind by accepting Regex patterns as arguments and doing some kind of find-replace in the resulting string to only return the desired match group while omitting a (required but not captured) prefix?

neophlegm
  • 345
  • 1
  • 12

2 Answers2

1

The following function accepts three arguments in order to satisfy this problem: a string to be matched, the regex pattern of a non-capturable prefix, and the regex pattern of the subsequent capture group.

Function LookBehindRegex(ByVal inputText As String, nonCaptureRegex As String, _
   captureRegex As String)

    'Non capturing lookbehind to retrieve reference preceded by a regex group

    Dim regEx As New RegExp
    Dim intermediate As String
    Dim nonCaptureText As String

    regEx.IgnoreCase = True
    'First set the capture pattern to both regex groups, to capture the whole text
    regEx.Pattern = "(" & nonCaptureRegex & ")" & "(" & captureRegex & ")"
    'Store that
    intermediate = regEx.Execute(inputText)(0)
    'Next, set the pattern to only capture the non-capture regex
    regEx.Pattern = nonCaptureRegex
    'Store the non-capturable text from the intermediate result
    nonCaptureText = regEx.Execute(intermediate)(0)
    'Finally remove the non-capture text from the intermediate result
    LookBehindRegex = Replace(intermediate, nonCaptureText, "")

End Function

Limitations: This will only simulate positive lookbehind. The relevant Regular Expressions module must be added as a reference to the VB project.

T.M.
  • 6,659
  • 3
  • 24
  • 42
neophlegm
  • 345
  • 1
  • 12
0

Wouldn't this give the same result as your answer, with less work? (Of course, it needs error checking added to it.)

Function LookBehindRegex( _
    ByVal inputText As String, nonCaptureRegex As String, _
    captureRegex As String) As String

    Dim regEx As New RegExp
    Dim mac As MatchCollection

    regEx.IgnoreCase = True
    regEx.Pattern = "(" & nonCaptureRegex & ")(" & captureRegex & ")"

    Set mac = regEx.Execute(inputText)
    If mac.Count > 0 Then _
        LookBehindRegex = mac(0).SubMatches(1)

End Function
someprogrammer
  • 207
  • 2
  • 12