0

I have a regexp that tries to find multiple sub captures within matches:

https://regex101.com/r/nk1Q5J/2/

=\s?.*(?:((?i)Fields\("(\w+)"\)\.Value\)*?))

I've had simpler versions with equivalent results but this is the last iteration.

the Trick here is that the first group looks for a sequence that begins with '=' (to identify database field reads in VB.Net)

The single sub capture cases work:

Match 1. [comparison + single parameter read call] = False And IsNull(Fields("lmpRoundedEndTime").Value)

=> G2: lmpRoundedEndTime

Match 3. [read into string] oRs.Open "select lmpEmployeeID,lmpShiftID,lmpTimecardDate,lmpProjectID from Timecards where lmpTimecardID = " + App.Convert.NumberToSql(Fields("lmlTimecardID").Value),Connection,adOpenStatic,adLockReadOnly,adCmdText

=> G2: lmlTimecardID

Match 4. [assignment] Fields("lmlEmployeeID").Value = oRs.Fields("lmpEmployeeID").Value

Where I am failing is a match with multiple sub-captures. My regexp returns the last (intended) sub capture :

Match 2. [read multiple input parameters] Fields("lmpPayrollHours").Value = App.Ax("TimecardFunctions").CalculateHours(Fields("lmpShiftID").Value,Fields("lmpRoundedStartTime").Value,Fields("lmpRoundedEndTime").Value)

=> G2: lmpRoundedEndTime

'''''''''''' ^ must capture: lmpShiftID , lmpRoundedStartTime , lmpRoundedEndTime

I've read up on lazy quantifiers etc, but can't wrap my head around where this goes wrong.

References:

https://www.regular-expressions.info/refrepeat.html

http://www.rexegg.com/regex-quantifiers.html

Related:

Regular expression: repeating groups only getting last group

What's the difference between "groups" and "captures" in .NET regular expressions?

BTW, I could quantify the sub capture as {1,5} safely for efficiency, but that's not the focus.

EDIT:

By using negative lookahead to exclude the left side of comparisons, this got me much closer (match 2 above now works):

(?:Fields\("(\w+)"\)\.Value)(?!\)?\s{0,2}[=|<])

but in the following block of code, only the first two are captured:

        If oRs.EOF = False Then
            If CInt(Fields("lmlTimecardType").Value) = 1 Then
                If Trim(oRs.Fields("lmeDirectExpenseID").Value) <> "" Then
                    Fields("lmlExpenseID").Value = oRs.Fields("lmeDirectExpenseID").Value
                End If
            Else
                If Trim(oRs.Fields("lmeIndirectExpenseID").Value) <> "" Then
                    Fields("lmlExpenseID").Value = oRs.Fields("lmeIndirectExpenseID").Value
                End If
            End If
            If CInt(Fields("lmlTimecardType").Value) = 2 Then
                If Trim(oRs.FIelds("lmeDefaultWorkCenterID").Value) <> "" Then
                    Fields("lmlWorkCenterID").Value = oRs.FIelds("lmeDefaultWorkCenterID").Value
                End If
            End If
        End If

Capture1:

Fields("lmlExpenseID").Value = oRs.Fields("lmeDirectExpenseID").Value

Capture2:

Fields("lmlExpenseID").Value = oRs.Fields("lmeIndirectExpenseID").Value

Capture3 (failed):

Fields("lmlWorkCenterID").Value = oRs.FIelds("lmeDefaultWorkCenterID").Value

1 Answers1

0

Actually, (?:Fields\("(\w+)"\)\.Value)(?!\)?\s{0,2}[=|<]) does work in my Excel sheet, just not in the regex101 test. Probably a slightly different standard used there.

https://regex101.com/r/p6zFqy/1/

passing pattern test