diff --git a/regex/compile.go b/regex/compile.go index f2db284..6ba669f 100644 --- a/regex/compile.go +++ b/regex/compile.go @@ -945,6 +945,10 @@ func shuntingYard(re string, flags ...ReFlag) ([]postfixNode, error) { } outQueue[idx].startReps = startRangeNum outQueue[idx].endReps = endRangeNum + if i < len(re_postfix)-1 && re_postfix[i+1] == '?' { // lazy repitition + outQueue[idx].isLazy = true + i++ + } } if c == '(' || c == nonCapLparenRune { opStack = append(opStack, c) @@ -1238,6 +1242,9 @@ func thompson(re []postfixNode) (Reg, error) { if err != nil { return Reg{}, err } + if c.isLazy { + stateToAdd.isLazy = true + } nfa = append(nfa, stateToAdd) case plusNode: // a+ is equivalent to aa* s1 := mustPop(&nfa) @@ -1245,6 +1252,9 @@ func thompson(re []postfixNode) (Reg, error) { if err != nil { return Reg{}, err } + if c.isLazy { + s2.isLazy = true + } s1 = concatenate(s1, s2) nfa = append(nfa, s1) case questionNode: // ab? is equivalent to a(b|) @@ -1256,6 +1266,9 @@ func thompson(re []postfixNode) (Reg, error) { if err != nil { return Reg{}, err } + if c.isLazy { + s2.isLazy = true + } nfa = append(nfa, s2) case pipeNode: // A pipe operator doesn't actually need either operand to be present. If an operand isn't present, @@ -1311,6 +1324,9 @@ func thompson(re []postfixNode) (Reg, error) { if err != nil { return Reg{}, err } + if c.isLazy { + s2.isLazy = true + } stateToAdd = concatenate(stateToAdd, s2) } else { // Case 2 for i := c.startReps; i < c.endReps; i++ { @@ -1318,6 +1334,9 @@ func thompson(re []postfixNode) (Reg, error) { if err != nil { return Reg{}, fmt.Errorf("error processing bounded repetition") } + if c.isLazy { + tmp.isLazy = true + } stateToAdd = concatenate(stateToAdd, tmp) } }