LEFT | RIGHT |
(no file at all) | |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // Package regexp implements regular expression search. | 5 // Package regexp implements regular expression search. |
6 // | 6 // |
7 // The syntax of the regular expressions accepted is the same | 7 // The syntax of the regular expressions accepted is the same |
8 // general syntax used by Perl, Python, and other languages. | 8 // general syntax used by Perl, Python, and other languages. |
9 // More precisely, it is the syntax accepted by RE2 and described at | 9 // More precisely, it is the syntax accepted by RE2 and described at |
10 // http://code.google.com/p/re2/wiki/Syntax, except for \C. | 10 // http://code.google.com/p/re2/wiki/Syntax, except for \C. |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
78 prog *syntax.Prog // compiled program | 78 prog *syntax.Prog // compiled program |
79 prefix string // required prefix in unanchored matches | 79 prefix string // required prefix in unanchored matches |
80 prefixBytes []byte // prefix, as a []byte | 80 prefixBytes []byte // prefix, as a []byte |
81 prefixComplete bool // prefix is the entire regexp | 81 prefixComplete bool // prefix is the entire regexp |
82 prefixRune rune // first rune in prefix | 82 prefixRune rune // first rune in prefix |
83 cond syntax.EmptyOp // empty-width conditions required at star
t of match | 83 cond syntax.EmptyOp // empty-width conditions required at star
t of match |
84 numSubexp int | 84 numSubexp int |
85 subexpNames []string | 85 subexpNames []string |
86 longest bool | 86 longest bool |
87 | 87 |
88 » // cache of machines for running regexp | 88 » // pool of machines for running regexp |
89 » mu sync.Mutex | 89 » machinePool sync.Pool // of *machine |
90 » machine []*machine | |
91 } | 90 } |
92 | 91 |
93 // String returns the source text used to compile the regular expression. | 92 // String returns the source text used to compile the regular expression. |
94 func (re *Regexp) String() string { | 93 func (re *Regexp) String() string { |
95 return re.expr | 94 return re.expr |
96 } | 95 } |
97 | 96 |
98 // Compile parses a regular expression and returns, if successful, | 97 // Compile parses a regular expression and returns, if successful, |
99 // a Regexp object that can be used to match against text. | 98 // a Regexp object that can be used to match against text. |
100 // | 99 // |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
168 regexp.prefixBytes = []byte(regexp.prefix) | 167 regexp.prefixBytes = []byte(regexp.prefix) |
169 regexp.prefixRune, _ = utf8.DecodeRuneInString(regexp.prefix) | 168 regexp.prefixRune, _ = utf8.DecodeRuneInString(regexp.prefix) |
170 } | 169 } |
171 return regexp, nil | 170 return regexp, nil |
172 } | 171 } |
173 | 172 |
174 // get returns a machine to use for matching re. | 173 // get returns a machine to use for matching re. |
175 // It uses the re's machine cache if possible, to avoid | 174 // It uses the re's machine cache if possible, to avoid |
176 // unnecessary allocation. | 175 // unnecessary allocation. |
177 func (re *Regexp) get() *machine { | 176 func (re *Regexp) get() *machine { |
178 » re.mu.Lock() | 177 » if v := re.machinePool.Get(); v != nil { |
179 » if n := len(re.machine); n > 0 { | 178 » » return v.(*machine) |
180 » » z := re.machine[n-1] | 179 » } |
181 » » re.machine = re.machine[:n-1] | |
182 » » re.mu.Unlock() | |
183 » » return z | |
184 » } | |
185 » re.mu.Unlock() | |
186 z := progMachine(re.prog) | 180 z := progMachine(re.prog) |
187 z.re = re | 181 z.re = re |
188 return z | 182 return z |
189 } | 183 } |
190 | 184 |
191 // put returns a machine to the re's machine cache. | 185 // put returns a machine to the re's machine cache. |
192 // There is no attempt to limit the size of the cache, so it will | 186 // There is no attempt to limit the size of the cache, so it will |
193 // grow to the maximum number of simultaneous matches | 187 // grow to the maximum number of simultaneous matches |
194 // run using re. (The cache empties when re gets garbage collected.) | 188 // run using re. (The cache empties when re gets garbage collected.) |
195 func (re *Regexp) put(z *machine) { | 189 func (re *Regexp) put(z *machine) { |
196 » re.mu.Lock() | 190 » re.machinePool.Put(z) |
197 » re.machine = append(re.machine, z) | |
198 » re.mu.Unlock() | |
199 } | 191 } |
200 | 192 |
201 // MustCompile is like Compile but panics if the expression cannot be parsed. | 193 // MustCompile is like Compile but panics if the expression cannot be parsed. |
202 // It simplifies safe initialization of global variables holding compiled regula
r | 194 // It simplifies safe initialization of global variables holding compiled regula
r |
203 // expressions. | 195 // expressions. |
204 func MustCompile(str string) *Regexp { | 196 func MustCompile(str string) *Regexp { |
205 regexp, error := Compile(str) | 197 regexp, error := Compile(str) |
206 if error != nil { | 198 if error != nil { |
207 panic(`regexp: Compile(` + quote(str) + `): ` + error.Error()) | 199 panic(`regexp: Compile(` + quote(str) + `): ` + error.Error()) |
208 } | 200 } |
(...skipping 888 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1097 } | 1089 } |
1098 beg = match[1] | 1090 beg = match[1] |
1099 } | 1091 } |
1100 | 1092 |
1101 if end != len(s) { | 1093 if end != len(s) { |
1102 strings = append(strings, s[beg:]) | 1094 strings = append(strings, s[beg:]) |
1103 } | 1095 } |
1104 | 1096 |
1105 return strings | 1097 return strings |
1106 } | 1098 } |
LEFT | RIGHT |