Fixed bug with lookaheads: f(?=f) would not match anything in 'ffa', because of the 'a' at the end of the string. Fixed by checking if there are other last states when an assertion fails, rather than immediately aborting
This commit is contained in:
30
matching.go
30
matching.go
@@ -173,6 +173,8 @@ func findAllMatchesHelper(start *State, str []rune, offset int) (bool, MatchInde
|
||||
// Take any transitions corresponding to current character
|
||||
numStatesMatched := 0 // The number of states which had at least 1 match for this round
|
||||
assertionFailed := false // Whether or not an assertion failed for this round
|
||||
lastStateInList := false // Whether or not a last state was in our list of states
|
||||
// lastStateLookaround := false // Whether or not a last state (that is also a lookaround) matched
|
||||
for _, state := range currentStates {
|
||||
matches, numMatches := state.matchesFor(str, i)
|
||||
if numMatches > 0 {
|
||||
@@ -184,16 +186,30 @@ func findAllMatchesHelper(start *State, str []rune, offset int) (bool, MatchInde
|
||||
assertionFailed = true
|
||||
}
|
||||
if state.isLast {
|
||||
endIdx = i
|
||||
tempIndices, _ = unique_append(tempIndices, MatchIndex{startIdx, endIdx})
|
||||
lastStateInList = true
|
||||
}
|
||||
}
|
||||
if assertionFailed && numStatesMatched == 0 { // Nothing has matched and an assertion has failed - abort
|
||||
if i == startingFrom {
|
||||
i++
|
||||
|
||||
if assertionFailed && numStatesMatched == 0 { // Nothing has matched and an assertion has failed
|
||||
// One of the states in our list was a last state. In this case, we
|
||||
// don't abort upon the failure of an assertion, because we have found
|
||||
// another path to a final state.
|
||||
// Even if the last state _was_ an assertion, we can use the previously
|
||||
// saved indices to find a match.
|
||||
if lastStateInList {
|
||||
break
|
||||
} else {
|
||||
if i == startingFrom {
|
||||
i++
|
||||
}
|
||||
return false, MatchIndex{}, i
|
||||
}
|
||||
return false, MatchIndex{}, i
|
||||
}
|
||||
if lastStateInList { // A last-state was in the list of states. add the matchIndex to our MatchIndex list
|
||||
endIdx = i
|
||||
tempIndices, _ = unique_append(tempIndices, MatchIndex{startIdx, endIdx})
|
||||
}
|
||||
|
||||
// Check if we can find a zero-length match
|
||||
if foundPath == false {
|
||||
if zeroMatchPossible(str, i, currentStates...) {
|
||||
@@ -250,7 +266,7 @@ func findAllMatchesHelper(start *State, str []rune, offset int) (bool, MatchInde
|
||||
// Only add the match if the start index is in bounds. If the state has an assertion,
|
||||
// make sure the assertion checks out.
|
||||
if state.isLast && startIdx < len(str) {
|
||||
if state.assert == NONE || state.checkAssertion(str, len(str)) {
|
||||
if state.assert == NONE || state.checkAssertion(str, i) {
|
||||
endIdx = i
|
||||
tempIndices, _ = unique_append(tempIndices, MatchIndex{startIdx, endIdx})
|
||||
}
|
||||
|
Reference in New Issue
Block a user