annotate vendor/github.com/dlclark/regexp2/replace.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 "errors"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
6
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
7 "github.com/dlclark/regexp2/syntax"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
8 )
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
9
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
10 const (
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
11 replaceSpecials = 4
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
12 replaceLeftPortion = -1
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
13 replaceRightPortion = -2
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
14 replaceLastGroup = -3
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
15 replaceWholeString = -4
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
16 )
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
17
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
18 // MatchEvaluator is a function that takes a match and returns a replacement string to be used
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
19 type MatchEvaluator func(Match) string
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
20
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
21 // Three very similar algorithms appear below: replace (pattern),
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
22 // replace (evaluator), and split.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
23
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
24 // Replace Replaces all occurrences of the regex in the string with the
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
25 // replacement pattern.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
26 //
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
27 // Note that the special case of no matches is handled on its own:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
28 // with no matches, the input string is returned unchanged.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
29 // The right-to-left case is split out because StringBuilder
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
30 // doesn't handle right-to-left string building directly very well.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
31 func replace(regex *Regexp, data *syntax.ReplacerData, evaluator MatchEvaluator, input string, startAt, count int) (string, error) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
32 if count < -1 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
33 return "", errors.New("Count too small")
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
34 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
35 if count == 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
36 return "", nil
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
37 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
38
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
39 m, err := regex.FindStringMatchStartingAt(input, startAt)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
40
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
41 if err != nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
42 return "", err
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
43 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
44 if m == nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
45 return input, nil
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
46 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
47
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
48 buf := &bytes.Buffer{}
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
49 text := m.text
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
50
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
51 if !regex.RightToLeft() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
52 prevat := 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
53 for m != nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
54 if m.Index != prevat {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
55 buf.WriteString(string(text[prevat:m.Index]))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
56 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
57 prevat = m.Index + m.Length
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
58 if evaluator == nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
59 replacementImpl(data, buf, m)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
60 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
61 buf.WriteString(evaluator(*m))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
62 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
63
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
64 count--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
65 if count == 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
66 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
67 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
68 m, err = regex.FindNextMatch(m)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
69 if err != nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
70 return "", nil
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
71 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
72 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
73
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
74 if prevat < len(text) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
75 buf.WriteString(string(text[prevat:]))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
76 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
77 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
78 prevat := len(text)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
79 var al []string
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
80
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
81 for m != nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
82 if m.Index+m.Length != prevat {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
83 al = append(al, string(text[m.Index+m.Length:prevat]))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
84 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
85 prevat = m.Index
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
86 if evaluator == nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
87 replacementImplRTL(data, &al, m)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
88 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
89 al = append(al, evaluator(*m))
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 count--
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
93 if count == 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
94 break
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
95 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
96 m, err = regex.FindNextMatch(m)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
97 if err != nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
98 return "", nil
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
99 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
100 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
101
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
102 if prevat > 0 {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
103 buf.WriteString(string(text[:prevat]))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
104 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
105
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
106 for i := len(al) - 1; i >= 0; i-- {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
107 buf.WriteString(al[i])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
108 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
109 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
110
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
111 return buf.String(), nil
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
112 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
113
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
114 // Given a Match, emits into the StringBuilder the evaluated
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
115 // substitution pattern.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
116 func replacementImpl(data *syntax.ReplacerData, buf *bytes.Buffer, m *Match) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
117 for _, r := range data.Rules {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
118
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
119 if r >= 0 { // string lookup
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
120 buf.WriteString(data.Strings[r])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
121 } else if r < -replaceSpecials { // group lookup
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
122 m.groupValueAppendToBuf(-replaceSpecials-1-r, buf)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
123 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
124 switch -replaceSpecials - 1 - r { // special insertion patterns
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
125 case replaceLeftPortion:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
126 for i := 0; i < m.Index; i++ {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
127 buf.WriteRune(m.text[i])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
128 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
129 case replaceRightPortion:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
130 for i := m.Index + m.Length; i < len(m.text); i++ {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
131 buf.WriteRune(m.text[i])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
132 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
133 case replaceLastGroup:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
134 m.groupValueAppendToBuf(m.GroupCount()-1, buf)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
135 case replaceWholeString:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
136 for i := 0; i < len(m.text); i++ {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
137 buf.WriteRune(m.text[i])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
138 }
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 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
143
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
144 func replacementImplRTL(data *syntax.ReplacerData, al *[]string, m *Match) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
145 l := *al
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
146 buf := &bytes.Buffer{}
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
147
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
148 for _, r := range data.Rules {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
149 buf.Reset()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
150 if r >= 0 { // string lookup
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
151 l = append(l, data.Strings[r])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
152 } else if r < -replaceSpecials { // group lookup
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
153 m.groupValueAppendToBuf(-replaceSpecials-1-r, buf)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
154 l = append(l, buf.String())
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
155 } else {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
156 switch -replaceSpecials - 1 - r { // special insertion patterns
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
157 case replaceLeftPortion:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
158 for i := 0; i < m.Index; i++ {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
159 buf.WriteRune(m.text[i])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
160 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
161 case replaceRightPortion:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
162 for i := m.Index + m.Length; i < len(m.text); i++ {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
163 buf.WriteRune(m.text[i])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
164 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
165 case replaceLastGroup:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
166 m.groupValueAppendToBuf(m.GroupCount()-1, buf)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
167 case replaceWholeString:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
168 for i := 0; i < len(m.text); i++ {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
169 buf.WriteRune(m.text[i])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
170 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
171 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
172 l = append(l, buf.String())
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
173 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
174 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
175
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
176 *al = l
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
177 }