File: matchRanges.go

package info (click to toggle)
moor 2.0.0-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 16,112 kB
  • sloc: sh: 174; ansic: 12; xml: 6; makefile: 5
file content (73 lines) | stat: -rw-r--r-- 1,656 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package reader

import "regexp"

// MatchRanges collects match indices
type MatchRanges struct {
	Matches [][2]int
}

// getMatchRanges locates one or more regexp matches in a string
func getMatchRanges(String *string, Pattern *regexp.Regexp) *MatchRanges {
	if Pattern == nil {
		return nil
	}

	return &MatchRanges{
		Matches: toRunePositions(Pattern.FindAllStringIndex(*String, -1), String),
	}
}

// Convert byte indices to rune indices
func toRunePositions(byteIndices [][]int, matchedString *string) [][2]int {
	var returnMe [][2]int
	if len(byteIndices) == 0 {
		// Nothing to see here, move along
		return returnMe
	}

	runeIndex := 0
	byteIndicesToRuneIndices := make(map[int]int, 0)
	for byteIndex := range *matchedString {
		byteIndicesToRuneIndices[byteIndex] = runeIndex

		runeIndex++
	}

	// If a match touches the end of the string, that will be encoded as one
	// byte past the end of the string. Therefore we must add a mapping for
	// first-index-after-the-end.
	byteIndicesToRuneIndices[len(*matchedString)] = runeIndex

	for _, bytePair := range byteIndices {
		fromRuneIndex := byteIndicesToRuneIndices[bytePair[0]]
		toRuneIndex := byteIndicesToRuneIndices[bytePair[1]]
		returnMe = append(returnMe, [2]int{fromRuneIndex, toRuneIndex})
	}

	return returnMe
}

// InRange says true if the index is part of a regexp match
func (mr *MatchRanges) InRange(index int) bool {
	if mr == nil {
		return false
	}

	for _, match := range mr.Matches {
		matchFirstIndex := match[0]
		matchLastIndex := match[1] - 1

		if index < matchFirstIndex {
			continue
		}

		if index > matchLastIndex {
			continue
		}

		return true
	}

	return false
}