Skip to content

Commit

Permalink
Add helper methods for the regex and fuzzy automatons (#22)
Browse files Browse the repository at this point in the history
- Add MatchAndDistance API to DFA automaton for fuzzy matching using
Levenshtein distance.
- Add MatchesRegex API to regex automaton for validating input against
the pattern.
  • Loading branch information
CascadingRadium authored Dec 11, 2024
1 parent ad113db commit 4fab6f2
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 0 deletions.
1 change: 1 addition & 0 deletions automaton.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,5 @@ var alwaysMatchAutomaton = &AlwaysMatch{}
type FuzzyAutomaton interface {
Automaton
EditDistance(int) uint8
MatchAndDistance(input string) (bool, uint8)
}
18 changes: 18 additions & 0 deletions levenshtein/dfa.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,24 @@ func (d *DFA) EditDistance(stateId int) uint8 {
return d.distances[stateId].distance()
}

func (d *DFA) MatchAndDistance(input string) (bool, uint8) {
currentState := d.Start()
index := 0
// Traverse the DFA while characters can still match
for d.CanMatch(currentState) && index < len(input) {
currentState = d.Accept(currentState, input[index])
if currentState == int(SinkState) {
break
}
index++
}
// Ensure we've processed the entire input and check if the current state is a match
if index == len(input) && d.IsMatch(currentState) {
return true, d.EditDistance(currentState)
}
return false, 0
}

// Returns the number of states in the `DFA`.
func (d *DFA) numStates() int {
return len(d.transitions)
Expand Down
11 changes: 11 additions & 0 deletions regexp/regexp.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,3 +117,14 @@ func (r *Regexp) Accept(s int, b byte) int {
}
return 0
}

func (r *Regexp) MatchesRegex(input string) bool {
currentState := r.Start()
index := 0
// Traverse the DFA while characters can still match
for r.CanMatch(currentState) && index < len(input) {
currentState = r.Accept(currentState, input[index])
index++
}
return index == len(input) && r.IsMatch(currentState)
}

0 comments on commit 4fab6f2

Please sign in to comment.