annotate vendor/github.com/dlclark/regexp2/match.go @ 66:787b5ee0289d draft

Use vendored modules Signed-off-by: Izuru Yakumo <yakumo.izuru@chaotic.ninja>
author yakumo.izuru
date Sun, 23 Jul 2023 13:18:53 +0000
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
66
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1 package regexp2
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
2
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
3 import (
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
4 "bytes"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
5 "fmt"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
6 )
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
7
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
8 // Match is a single regex result match that contains groups and repeated captures
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
9 // -Groups
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
10 // -Capture
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
11 type Match struct {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
12 Group //embeded group 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
13
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
14 regex *Regexp
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
15 otherGroups []Group
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
16
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
17 // input to the match
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
18 textpos int
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
19 textstart int
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
20
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
21 capcount int
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
22 caps []int
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
23 sparseCaps map[int]int
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
24
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
25 // output from the match
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
26 matches [][]int
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
27 matchcount []int
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
28
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
29 // whether we've done any balancing with this match. If we
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
30 // have done balancing, we'll need to do extra work in Tidy().
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
31 balancing bool
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
32 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
33
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
34 // Group is an explicit or implit (group 0) matched group within the pattern
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
35 type Group struct {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
36 Capture // the last capture of this group is embeded for ease of use
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
37
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
38 Name string // group name
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
39 Captures []Capture // captures of this group
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
40 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
41
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
42 // Capture is a single capture of text within the larger original string
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
43 type Capture struct {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
44 // the original string
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
45 text []rune
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
46 // the position in the original string where the first character of
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
47 // captured substring was found.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
48 Index int
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
49 // the length of the captured substring.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
50 Length int
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
51 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
52
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
53 // String returns the captured text as a String
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
54 func (c *Capture) String() string {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
55 return string(c.text[c.Index : c.Index+c.Length])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
56 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
57
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
58 // Runes returns the captured text as a rune slice
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
59 func (c *Capture) Runes() []rune {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
60 return c.text[c.Index : c.Index+c.Length]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
61 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
62
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
63 func newMatch(regex *Regexp, capcount int, text []rune, startpos int) *Match {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
64 m := Match{
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
65 regex: regex,
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
66 matchcount: make([]int, capcount),
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
67 matches: make([][]int, capcount),
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
68 textstart: startpos,
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
69 balancing: false,
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
70 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
71 m.Name = "0"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
72 m.text = text
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
73 m.matches[0] = make([]int, 2)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
74 return &m
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
75 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
76
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
77 func newMatchSparse(regex *Regexp, caps map[int]int, capcount int, text []rune, startpos int) *Match {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
78 m := newMatch(regex, capcount, text, startpos)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
79 m.sparseCaps = caps
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
80 return m
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
81 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
82
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
83 func (m *Match) reset(text []rune, textstart int) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
84 m.text = text
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
85 m.textstart = textstart
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
86 for i := 0; i < len(m.matchcount); i++ {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
87 m.matchcount[i] = 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
88 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
89 m.balancing = false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
90 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
91
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
92 func (m *Match) tidy(textpos int) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
93
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
94 interval := m.matches[0]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
95 m.Index = interval[0]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
96 m.Length = interval[1]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
97 m.textpos = textpos
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
98 m.capcount = m.matchcount[0]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
99 //copy our root capture to the list
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
100 m.Group.Captures = []Capture{m.Group.Capture}
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
101
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
102 if m.balancing {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
103 // The idea here is that we want to compact all of our unbalanced captures. To do that we
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
104 // use j basically as a count of how many unbalanced captures we have at any given time
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
105 // (really j is an index, but j/2 is the count). First we skip past all of the real captures
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
106 // until we find a balance captures. Then we check each subsequent entry. If it's a balance
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
107 // capture (it's negative), we decrement j. If it's a real capture, we increment j and copy
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
108 // it down to the last free position.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
109 for cap := 0; cap < len(m.matchcount); cap++ {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
110 limit := m.matchcount[cap] * 2
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
111 matcharray := m.matches[cap]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
112
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
113 var i, j int
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
114
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
115 for i = 0; i < limit; i++ {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
116 if matcharray[i] < 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
117 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
118 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
119 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
120
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
121 for j = i; i < limit; i++ {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
122 if matcharray[i] < 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
123 // skip negative values
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
124 j--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
125 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
126 // but if we find something positive (an actual capture), copy it back to the last
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
127 // unbalanced position.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
128 if i != j {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
129 matcharray[j] = matcharray[i]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
130 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
131 j++
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
132 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
133 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
134
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
135 m.matchcount[cap] = j / 2
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
136 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
137
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
138 m.balancing = false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
139 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
140 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
141
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
142 // isMatched tells if a group was matched by capnum
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
143 func (m *Match) isMatched(cap int) bool {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
144 return cap < len(m.matchcount) && m.matchcount[cap] > 0 && m.matches[cap][m.matchcount[cap]*2-1] != (-3+1)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
145 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
146
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
147 // matchIndex returns the index of the last specified matched group by capnum
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
148 func (m *Match) matchIndex(cap int) int {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
149 i := m.matches[cap][m.matchcount[cap]*2-2]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
150 if i >= 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
151 return i
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
152 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
153
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
154 return m.matches[cap][-3-i]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
155 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
156
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
157 // matchLength returns the length of the last specified matched group by capnum
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
158 func (m *Match) matchLength(cap int) int {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
159 i := m.matches[cap][m.matchcount[cap]*2-1]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
160 if i >= 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
161 return i
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
162 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
163
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
164 return m.matches[cap][-3-i]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
165 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
166
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
167 // Nonpublic builder: add a capture to the group specified by "c"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
168 func (m *Match) addMatch(c, start, l int) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
169
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
170 if m.matches[c] == nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
171 m.matches[c] = make([]int, 2)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
172 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
173
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
174 capcount := m.matchcount[c]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
175
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
176 if capcount*2+2 > len(m.matches[c]) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
177 oldmatches := m.matches[c]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
178 newmatches := make([]int, capcount*8)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
179 copy(newmatches, oldmatches[:capcount*2])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
180 m.matches[c] = newmatches
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
181 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
182
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
183 m.matches[c][capcount*2] = start
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
184 m.matches[c][capcount*2+1] = l
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
185 m.matchcount[c] = capcount + 1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
186 //log.Printf("addMatch: c=%v, i=%v, l=%v ... matches: %v", c, start, l, m.matches)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
187 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
188
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
189 // Nonpublic builder: Add a capture to balance the specified group. This is used by the
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
190 // balanced match construct. (?<foo-foo2>...)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
191 //
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
192 // If there were no such thing as backtracking, this would be as simple as calling RemoveMatch(c).
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
193 // However, since we have backtracking, we need to keep track of everything.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
194 func (m *Match) balanceMatch(c int) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
195 m.balancing = true
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
196
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
197 // we'll look at the last capture first
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
198 capcount := m.matchcount[c]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
199 target := capcount*2 - 2
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
200
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
201 // first see if it is negative, and therefore is a reference to the next available
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
202 // capture group for balancing. If it is, we'll reset target to point to that capture.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
203 if m.matches[c][target] < 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
204 target = -3 - m.matches[c][target]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
205 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
206
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
207 // move back to the previous capture
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
208 target -= 2
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
209
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
210 // if the previous capture is a reference, just copy that reference to the end. Otherwise, point to it.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
211 if target >= 0 && m.matches[c][target] < 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
212 m.addMatch(c, m.matches[c][target], m.matches[c][target+1])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
213 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
214 m.addMatch(c, -3-target, -4-target /* == -3 - (target + 1) */)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
215 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
216 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
217
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
218 // Nonpublic builder: removes a group match by capnum
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
219 func (m *Match) removeMatch(c int) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
220 m.matchcount[c]--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
221 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
222
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
223 // GroupCount returns the number of groups this match has matched
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
224 func (m *Match) GroupCount() int {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
225 return len(m.matchcount)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
226 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
227
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
228 // GroupByName returns a group based on the name of the group, or nil if the group name does not exist
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
229 func (m *Match) GroupByName(name string) *Group {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
230 num := m.regex.GroupNumberFromName(name)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
231 if num < 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
232 return nil
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
233 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
234 return m.GroupByNumber(num)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
235 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
236
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
237 // GroupByNumber returns a group based on the number of the group, or nil if the group number does not exist
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
238 func (m *Match) GroupByNumber(num int) *Group {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
239 // check our sparse map
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
240 if m.sparseCaps != nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
241 if newNum, ok := m.sparseCaps[num]; ok {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
242 num = newNum
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
243 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
244 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
245 if num >= len(m.matchcount) || num < 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
246 return nil
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
247 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
248
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
249 if num == 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
250 return &m.Group
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
251 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
252
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
253 m.populateOtherGroups()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
254
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
255 return &m.otherGroups[num-1]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
256 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
257
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
258 // Groups returns all the capture groups, starting with group 0 (the full match)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
259 func (m *Match) Groups() []Group {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
260 m.populateOtherGroups()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
261 g := make([]Group, len(m.otherGroups)+1)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
262 g[0] = m.Group
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
263 copy(g[1:], m.otherGroups)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
264 return g
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
265 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
266
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
267 func (m *Match) populateOtherGroups() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
268 // Construct all the Group objects first time called
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
269 if m.otherGroups == nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
270 m.otherGroups = make([]Group, len(m.matchcount)-1)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
271 for i := 0; i < len(m.otherGroups); i++ {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
272 m.otherGroups[i] = newGroup(m.regex.GroupNameFromNumber(i+1), m.text, m.matches[i+1], m.matchcount[i+1])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
273 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
274 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
275 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
276
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
277 func (m *Match) groupValueAppendToBuf(groupnum int, buf *bytes.Buffer) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
278 c := m.matchcount[groupnum]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
279 if c == 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
280 return
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
281 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
282
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
283 matches := m.matches[groupnum]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
284
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
285 index := matches[(c-1)*2]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
286 last := index + matches[(c*2)-1]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
287
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
288 for ; index < last; index++ {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
289 buf.WriteRune(m.text[index])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
290 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
291 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
292
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
293 func newGroup(name string, text []rune, caps []int, capcount int) Group {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
294 g := Group{}
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
295 g.text = text
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
296 if capcount > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
297 g.Index = caps[(capcount-1)*2]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
298 g.Length = caps[(capcount*2)-1]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
299 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
300 g.Name = name
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
301 g.Captures = make([]Capture, capcount)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
302 for i := 0; i < capcount; i++ {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
303 g.Captures[i] = Capture{
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
304 text: text,
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
305 Index: caps[i*2],
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
306 Length: caps[i*2+1],
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
307 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
308 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
309 //log.Printf("newGroup! capcount %v, %+v", capcount, g)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
310
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
311 return g
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
312 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
313
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
314 func (m *Match) dump() string {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
315 buf := &bytes.Buffer{}
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
316 buf.WriteRune('\n')
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
317 if len(m.sparseCaps) > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
318 for k, v := range m.sparseCaps {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
319 fmt.Fprintf(buf, "Slot %v -> %v\n", k, v)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
320 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
321 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
322
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
323 for i, g := range m.Groups() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
324 fmt.Fprintf(buf, "Group %v (%v), %v caps:\n", i, g.Name, len(g.Captures))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
325
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
326 for _, c := range g.Captures {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
327 fmt.Fprintf(buf, " (%v, %v) %v\n", c.Index, c.Length, c.String())
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
328 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
329 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
330 /*
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
331 for i := 0; i < len(m.matchcount); i++ {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
332 fmt.Fprintf(buf, "\nGroup %v (%v):\n", i, m.regex.GroupNameFromNumber(i))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
333
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
334 for j := 0; j < m.matchcount[i]; j++ {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
335 text := ""
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
336
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
337 if m.matches[i][j*2] >= 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
338 start := m.matches[i][j*2]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
339 text = m.text[start : start+m.matches[i][j*2+1]]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
340 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
341
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
342 fmt.Fprintf(buf, " (%v, %v) %v\n", m.matches[i][j*2], m.matches[i][j*2+1], text)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
343 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
344 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
345 */
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
346 return buf.String()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
347 }