diff --git a/cmd/main.go b/cmd/main.go index 61bc926..82c5748 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -137,7 +137,7 @@ func main() { fmt.Fprintf(out, "Line %d:\n", lineNum) } for _, m := range matchIndices { - fmt.Fprintf(out, "%s\n", m.ToString()) + fmt.Fprintf(out, "%s\n", m.String()) } err := out.Flush() if err != nil { diff --git a/regex/matching.go b/regex/matching.go index 1951484..104306f 100644 --- a/regex/matching.go +++ b/regex/matching.go @@ -35,10 +35,10 @@ func (m Match) numValidGroups() int { } // Returns a string containing the indices of all (valid) groups in the match -func (m Match) ToString() string { +func (m Match) String() string { var toRet string for i, g := range m { - if g.isValid() { + if g.IsValid() { toRet += fmt.Sprintf("Group %d\n", i) toRet += g.toString() toRet += "\n" @@ -52,8 +52,9 @@ func (idx Group) toString() string { return fmt.Sprintf("%d\t%d", idx.StartIdx, idx.EndIdx) } -// Returns whether a group contains valid indices -func (g Group) isValid() bool { +// Returns whether a group is valid (ie. whether it matched any text). It +// simply ensures that both indices of the group are >= 0. +func (g Group) IsValid() bool { return g.StartIdx >= 0 && g.EndIdx >= 0 } @@ -174,6 +175,20 @@ func (regex Reg) FindString(str string) string { return str[zeroGroup.StartIdx:zeroGroup.EndIdx] } +// FindSubmatch returns the leftmost match of the regex in the given string, including +// the submatches matched by capturing groups. The returned [Match] will always contain the same +// number of groups. The validity of a group (whether or not it matched anything) can be determined with +// [Group.IsValid], or by checking that both indices of the group are >= 0. +// The second-return value is nil if no match was found. +func (regex Reg) FindSubmatch(str string) (Match, error) { + match, err := regex.FindNthMatch(str, 1) + if err != nil { + return Match{}, fmt.Errorf("no match found") + } else { + return match, nil + } +} + // FindAllString is the 'all' version of FindString. // It returns a slice of strings containing the text of all matches of // the regex in the given string. @@ -372,7 +387,7 @@ func findAllSubmatchHelper(start *nfaState, str []rune, offset int, numGroups in // Check if we can find a zero-length match if foundPath == false { if ok := zeroMatchPossible(str, i, numGroups, currentStates...); ok { - if tempIndices[0].isValid() == false { + if tempIndices[0].IsValid() == false { tempIndices[0] = Group{startIdx, startIdx} } } @@ -382,7 +397,7 @@ func findAllSubmatchHelper(start *nfaState, str []rune, offset int, numGroups in startIdx++ // i++ // } - if tempIndices.numValidGroups() > 0 && tempIndices[0].isValid() { + if tempIndices.numValidGroups() > 0 && tempIndices[0].IsValid() { if tempIndices[0].StartIdx == tempIndices[0].EndIdx { // If we have a zero-length match, we have to shift the index at which we start. Otherwise we keep looking at the same paert of the string over and over. return true, tempIndices, tempIndices[0].EndIdx + 1 } else {