Source file
src/regexp/regexp.go
Documentation: regexp
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 package regexp
69
70 import (
71 "bytes"
72 "io"
73 "regexp/syntax"
74 "strconv"
75 "strings"
76 "sync"
77 "unicode"
78 "unicode/utf8"
79 )
80
81
82
83
84 type Regexp struct {
85 expr string
86 prog *syntax.Prog
87 onepass *onePassProg
88 numSubexp int
89 maxBitStateLen int
90 subexpNames []string
91 prefix string
92 prefixBytes []byte
93 prefixRune rune
94 prefixEnd uint32
95 mpool int
96 matchcap int
97 prefixComplete bool
98 cond syntax.EmptyOp
99 minInputLen int
100
101
102
103 longest bool
104 }
105
106
107 func (re *Regexp) String() string {
108 return re.expr
109 }
110
111
112
113
114
115
116
117
118
119 func (re *Regexp) Copy() *Regexp {
120 re2 := *re
121 return &re2
122 }
123
124
125
126
127
128
129
130
131
132
133
134 func Compile(expr string) (*Regexp, error) {
135 return compile(expr, syntax.Perl, false)
136 }
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157 func CompilePOSIX(expr string) (*Regexp, error) {
158 return compile(expr, syntax.POSIX, true)
159 }
160
161
162
163
164
165
166
167 func (re *Regexp) Longest() {
168 re.longest = true
169 }
170
171 func compile(expr string, mode syntax.Flags, longest bool) (*Regexp, error) {
172 re, err := syntax.Parse(expr, mode)
173 if err != nil {
174 return nil, err
175 }
176 maxCap := re.MaxCap()
177 capNames := re.CapNames()
178
179 re = re.Simplify()
180 prog, err := syntax.Compile(re)
181 if err != nil {
182 return nil, err
183 }
184 matchcap := prog.NumCap
185 if matchcap < 2 {
186 matchcap = 2
187 }
188 regexp := &Regexp{
189 expr: expr,
190 prog: prog,
191 onepass: compileOnePass(prog),
192 numSubexp: maxCap,
193 subexpNames: capNames,
194 cond: prog.StartCond(),
195 longest: longest,
196 matchcap: matchcap,
197 minInputLen: minInputLen(re),
198 }
199 if regexp.onepass == nil {
200 regexp.prefix, regexp.prefixComplete = prog.Prefix()
201 regexp.maxBitStateLen = maxBitStateLen(prog)
202 } else {
203 regexp.prefix, regexp.prefixComplete, regexp.prefixEnd = onePassPrefix(prog)
204 }
205 if regexp.prefix != "" {
206
207
208 regexp.prefixBytes = []byte(regexp.prefix)
209 regexp.prefixRune, _ = utf8.DecodeRuneInString(regexp.prefix)
210 }
211
212 n := len(prog.Inst)
213 i := 0
214 for matchSize[i] != 0 && matchSize[i] < n {
215 i++
216 }
217 regexp.mpool = i
218
219 return regexp, nil
220 }
221
222
223
224
225
226
227
228 var (
229 matchSize = [...]int{128, 512, 2048, 16384, 0}
230 matchPool [len(matchSize)]sync.Pool
231 )
232
233
234
235
236 func (re *Regexp) get() *machine {
237 m, ok := matchPool[re.mpool].Get().(*machine)
238 if !ok {
239 m = new(machine)
240 }
241 m.re = re
242 m.p = re.prog
243 if cap(m.matchcap) < re.matchcap {
244 m.matchcap = make([]int, re.matchcap)
245 for _, t := range m.pool {
246 t.cap = make([]int, re.matchcap)
247 }
248 }
249
250
251
252 n := matchSize[re.mpool]
253 if n == 0 {
254 n = len(re.prog.Inst)
255 }
256 if len(m.q0.sparse) < n {
257 m.q0 = queue{make([]uint32, n), make([]entry, 0, n)}
258 m.q1 = queue{make([]uint32, n), make([]entry, 0, n)}
259 }
260 return m
261 }
262
263
264 func (re *Regexp) put(m *machine) {
265 m.re = nil
266 m.p = nil
267 m.inputs.clear()
268 matchPool[re.mpool].Put(m)
269 }
270
271
272 func minInputLen(re *syntax.Regexp) int {
273 switch re.Op {
274 default:
275 return 0
276 case syntax.OpAnyChar, syntax.OpAnyCharNotNL, syntax.OpCharClass:
277 return 1
278 case syntax.OpLiteral:
279 l := 0
280 for _, r := range re.Rune {
281 if r == utf8.RuneError {
282 l++
283 } else {
284 l += utf8.RuneLen(r)
285 }
286 }
287 return l
288 case syntax.OpCapture, syntax.OpPlus:
289 return minInputLen(re.Sub[0])
290 case syntax.OpRepeat:
291 return re.Min * minInputLen(re.Sub[0])
292 case syntax.OpConcat:
293 l := 0
294 for _, sub := range re.Sub {
295 l += minInputLen(sub)
296 }
297 return l
298 case syntax.OpAlternate:
299 l := minInputLen(re.Sub[0])
300 var lnext int
301 for _, sub := range re.Sub[1:] {
302 lnext = minInputLen(sub)
303 if lnext < l {
304 l = lnext
305 }
306 }
307 return l
308 }
309 }
310
311
312
313
314 func MustCompile(str string) *Regexp {
315 regexp, err := Compile(str)
316 if err != nil {
317 panic(`regexp: Compile(` + quote(str) + `): ` + err.Error())
318 }
319 return regexp
320 }
321
322
323
324
325 func MustCompilePOSIX(str string) *Regexp {
326 regexp, err := CompilePOSIX(str)
327 if err != nil {
328 panic(`regexp: CompilePOSIX(` + quote(str) + `): ` + err.Error())
329 }
330 return regexp
331 }
332
333 func quote(s string) string {
334 if strconv.CanBackquote(s) {
335 return "`" + s + "`"
336 }
337 return strconv.Quote(s)
338 }
339
340
341 func (re *Regexp) NumSubexp() int {
342 return re.numSubexp
343 }
344
345
346
347
348
349
350 func (re *Regexp) SubexpNames() []string {
351 return re.subexpNames
352 }
353
354
355
356
357
358
359
360
361 func (re *Regexp) SubexpIndex(name string) int {
362 if name != "" {
363 for i, s := range re.subexpNames {
364 if name == s {
365 return i
366 }
367 }
368 }
369 return -1
370 }
371
372 const endOfText rune = -1
373
374
375
376 type input interface {
377 step(pos int) (r rune, width int)
378 canCheckPrefix() bool
379 hasPrefix(re *Regexp) bool
380 index(re *Regexp, pos int) int
381 context(pos int) lazyFlag
382 }
383
384
385 type inputString struct {
386 str string
387 }
388
389 func (i *inputString) step(pos int) (rune, int) {
390 if pos < len(i.str) {
391 c := i.str[pos]
392 if c < utf8.RuneSelf {
393 return rune(c), 1
394 }
395 return utf8.DecodeRuneInString(i.str[pos:])
396 }
397 return endOfText, 0
398 }
399
400 func (i *inputString) canCheckPrefix() bool {
401 return true
402 }
403
404 func (i *inputString) hasPrefix(re *Regexp) bool {
405 return strings.HasPrefix(i.str, re.prefix)
406 }
407
408 func (i *inputString) index(re *Regexp, pos int) int {
409 return strings.Index(i.str[pos:], re.prefix)
410 }
411
412 func (i *inputString) context(pos int) lazyFlag {
413 r1, r2 := endOfText, endOfText
414
415 if uint(pos-1) < uint(len(i.str)) {
416 r1 = rune(i.str[pos-1])
417 if r1 >= utf8.RuneSelf {
418 r1, _ = utf8.DecodeLastRuneInString(i.str[:pos])
419 }
420 }
421
422 if uint(pos) < uint(len(i.str)) {
423 r2 = rune(i.str[pos])
424 if r2 >= utf8.RuneSelf {
425 r2, _ = utf8.DecodeRuneInString(i.str[pos:])
426 }
427 }
428 return newLazyFlag(r1, r2)
429 }
430
431
432 type inputBytes struct {
433 str []byte
434 }
435
436 func (i *inputBytes) step(pos int) (rune, int) {
437 if pos < len(i.str) {
438 c := i.str[pos]
439 if c < utf8.RuneSelf {
440 return rune(c), 1
441 }
442 return utf8.DecodeRune(i.str[pos:])
443 }
444 return endOfText, 0
445 }
446
447 func (i *inputBytes) canCheckPrefix() bool {
448 return true
449 }
450
451 func (i *inputBytes) hasPrefix(re *Regexp) bool {
452 return bytes.HasPrefix(i.str, re.prefixBytes)
453 }
454
455 func (i *inputBytes) index(re *Regexp, pos int) int {
456 return bytes.Index(i.str[pos:], re.prefixBytes)
457 }
458
459 func (i *inputBytes) context(pos int) lazyFlag {
460 r1, r2 := endOfText, endOfText
461
462 if uint(pos-1) < uint(len(i.str)) {
463 r1 = rune(i.str[pos-1])
464 if r1 >= utf8.RuneSelf {
465 r1, _ = utf8.DecodeLastRune(i.str[:pos])
466 }
467 }
468
469 if uint(pos) < uint(len(i.str)) {
470 r2 = rune(i.str[pos])
471 if r2 >= utf8.RuneSelf {
472 r2, _ = utf8.DecodeRune(i.str[pos:])
473 }
474 }
475 return newLazyFlag(r1, r2)
476 }
477
478
479 type inputReader struct {
480 r io.RuneReader
481 atEOT bool
482 pos int
483 }
484
485 func (i *inputReader) step(pos int) (rune, int) {
486 if !i.atEOT && pos != i.pos {
487 return endOfText, 0
488
489 }
490 r, w, err := i.r.ReadRune()
491 if err != nil {
492 i.atEOT = true
493 return endOfText, 0
494 }
495 i.pos += w
496 return r, w
497 }
498
499 func (i *inputReader) canCheckPrefix() bool {
500 return false
501 }
502
503 func (i *inputReader) hasPrefix(re *Regexp) bool {
504 return false
505 }
506
507 func (i *inputReader) index(re *Regexp, pos int) int {
508 return -1
509 }
510
511 func (i *inputReader) context(pos int) lazyFlag {
512 return 0
513 }
514
515
516
517
518 func (re *Regexp) LiteralPrefix() (prefix string, complete bool) {
519 return re.prefix, re.prefixComplete
520 }
521
522
523
524 func (re *Regexp) MatchReader(r io.RuneReader) bool {
525 return re.doMatch(r, nil, "")
526 }
527
528
529
530 func (re *Regexp) MatchString(s string) bool {
531 return re.doMatch(nil, nil, s)
532 }
533
534
535
536 func (re *Regexp) Match(b []byte) bool {
537 return re.doMatch(nil, b, "")
538 }
539
540
541
542
543 func MatchReader(pattern string, r io.RuneReader) (matched bool, err error) {
544 re, err := Compile(pattern)
545 if err != nil {
546 return false, err
547 }
548 return re.MatchReader(r), nil
549 }
550
551
552
553
554 func MatchString(pattern string, s string) (matched bool, err error) {
555 re, err := Compile(pattern)
556 if err != nil {
557 return false, err
558 }
559 return re.MatchString(s), nil
560 }
561
562
563
564
565 func Match(pattern string, b []byte) (matched bool, err error) {
566 re, err := Compile(pattern)
567 if err != nil {
568 return false, err
569 }
570 return re.Match(b), nil
571 }
572
573
574
575
576 func (re *Regexp) ReplaceAllString(src, repl string) string {
577 n := 2
578 if strings.Contains(repl, "$") {
579 n = 2 * (re.numSubexp + 1)
580 }
581 b := re.replaceAll(nil, src, n, func(dst []byte, match []int) []byte {
582 return re.expand(dst, repl, nil, src, match)
583 })
584 return string(b)
585 }
586
587
588
589
590 func (re *Regexp) ReplaceAllLiteralString(src, repl string) string {
591 return string(re.replaceAll(nil, src, 2, func(dst []byte, match []int) []byte {
592 return append(dst, repl...)
593 }))
594 }
595
596
597
598
599
600 func (re *Regexp) ReplaceAllStringFunc(src string, repl func(string) string) string {
601 b := re.replaceAll(nil, src, 2, func(dst []byte, match []int) []byte {
602 return append(dst, repl(src[match[0]:match[1]])...)
603 })
604 return string(b)
605 }
606
607 func (re *Regexp) replaceAll(bsrc []byte, src string, nmatch int, repl func(dst []byte, m []int) []byte) []byte {
608 lastMatchEnd := 0
609 searchPos := 0
610 var buf []byte
611 var endPos int
612 if bsrc != nil {
613 endPos = len(bsrc)
614 } else {
615 endPos = len(src)
616 }
617 if nmatch > re.prog.NumCap {
618 nmatch = re.prog.NumCap
619 }
620
621 var dstCap [2]int
622 for searchPos <= endPos {
623 a := re.doExecute(nil, bsrc, src, searchPos, nmatch, dstCap[:0])
624 if len(a) == 0 {
625 break
626 }
627
628
629 if bsrc != nil {
630 buf = append(buf, bsrc[lastMatchEnd:a[0]]...)
631 } else {
632 buf = append(buf, src[lastMatchEnd:a[0]]...)
633 }
634
635
636
637
638
639 if a[1] > lastMatchEnd || a[0] == 0 {
640 buf = repl(buf, a)
641 }
642 lastMatchEnd = a[1]
643
644
645 var width int
646 if bsrc != nil {
647 _, width = utf8.DecodeRune(bsrc[searchPos:])
648 } else {
649 _, width = utf8.DecodeRuneInString(src[searchPos:])
650 }
651 if searchPos+width > a[1] {
652 searchPos += width
653 } else if searchPos+1 > a[1] {
654
655
656 searchPos++
657 } else {
658 searchPos = a[1]
659 }
660 }
661
662
663 if bsrc != nil {
664 buf = append(buf, bsrc[lastMatchEnd:]...)
665 } else {
666 buf = append(buf, src[lastMatchEnd:]...)
667 }
668
669 return buf
670 }
671
672
673
674
675 func (re *Regexp) ReplaceAll(src, repl []byte) []byte {
676 n := 2
677 if bytes.IndexByte(repl, '$') >= 0 {
678 n = 2 * (re.numSubexp + 1)
679 }
680 srepl := ""
681 b := re.replaceAll(src, "", n, func(dst []byte, match []int) []byte {
682 if len(srepl) != len(repl) {
683 srepl = string(repl)
684 }
685 return re.expand(dst, srepl, src, "", match)
686 })
687 return b
688 }
689
690
691
692
693 func (re *Regexp) ReplaceAllLiteral(src, repl []byte) []byte {
694 return re.replaceAll(src, "", 2, func(dst []byte, match []int) []byte {
695 return append(dst, repl...)
696 })
697 }
698
699
700
701
702
703 func (re *Regexp) ReplaceAllFunc(src []byte, repl func([]byte) []byte) []byte {
704 return re.replaceAll(src, "", 2, func(dst []byte, match []int) []byte {
705 return append(dst, repl(src[match[0]:match[1]])...)
706 })
707 }
708
709
710 var specialBytes [16]byte
711
712
713 func special(b byte) bool {
714 return b < utf8.RuneSelf && specialBytes[b%16]&(1<<(b/16)) != 0
715 }
716
717 func init() {
718 for _, b := range []byte(`\.+*?()|[]{}^$`) {
719 specialBytes[b%16] |= 1 << (b / 16)
720 }
721 }
722
723
724
725
726 func QuoteMeta(s string) string {
727
728 var i int
729 for i = 0; i < len(s); i++ {
730 if special(s[i]) {
731 break
732 }
733 }
734
735 if i >= len(s) {
736 return s
737 }
738
739 b := make([]byte, 2*len(s)-i)
740 copy(b, s[:i])
741 j := i
742 for ; i < len(s); i++ {
743 if special(s[i]) {
744 b[j] = '\\'
745 j++
746 }
747 b[j] = s[i]
748 j++
749 }
750 return string(b[:j])
751 }
752
753
754
755
756
757
758 func (re *Regexp) pad(a []int) []int {
759 if a == nil {
760
761 return nil
762 }
763 n := (1 + re.numSubexp) * 2
764 for len(a) < n {
765 a = append(a, -1)
766 }
767 return a
768 }
769
770
771
772
773 func (re *Regexp) allMatches(s string, b []byte, n int, deliver func([]int)) {
774 var end int
775 if b == nil {
776 end = len(s)
777 } else {
778 end = len(b)
779 }
780
781 for pos, i, prevMatchEnd := 0, 0, -1; i < n && pos <= end; {
782 matches := re.doExecute(nil, b, s, pos, re.prog.NumCap, nil)
783 if len(matches) == 0 {
784 break
785 }
786
787 accept := true
788 if matches[1] == pos {
789
790 if matches[0] == prevMatchEnd {
791
792
793 accept = false
794 }
795 var width int
796 if b == nil {
797 is := inputString{str: s}
798 _, width = is.step(pos)
799 } else {
800 ib := inputBytes{str: b}
801 _, width = ib.step(pos)
802 }
803 if width > 0 {
804 pos += width
805 } else {
806 pos = end + 1
807 }
808 } else {
809 pos = matches[1]
810 }
811 prevMatchEnd = matches[1]
812
813 if accept {
814 deliver(re.pad(matches))
815 i++
816 }
817 }
818 }
819
820
821
822 func (re *Regexp) Find(b []byte) []byte {
823 var dstCap [2]int
824 a := re.doExecute(nil, b, "", 0, 2, dstCap[:0])
825 if a == nil {
826 return nil
827 }
828 return b[a[0]:a[1]:a[1]]
829 }
830
831
832
833
834
835 func (re *Regexp) FindIndex(b []byte) (loc []int) {
836 a := re.doExecute(nil, b, "", 0, 2, nil)
837 if a == nil {
838 return nil
839 }
840 return a[0:2]
841 }
842
843
844
845
846
847
848 func (re *Regexp) FindString(s string) string {
849 var dstCap [2]int
850 a := re.doExecute(nil, nil, s, 0, 2, dstCap[:0])
851 if a == nil {
852 return ""
853 }
854 return s[a[0]:a[1]]
855 }
856
857
858
859
860
861 func (re *Regexp) FindStringIndex(s string) (loc []int) {
862 a := re.doExecute(nil, nil, s, 0, 2, nil)
863 if a == nil {
864 return nil
865 }
866 return a[0:2]
867 }
868
869
870
871
872
873
874 func (re *Regexp) FindReaderIndex(r io.RuneReader) (loc []int) {
875 a := re.doExecute(r, nil, "", 0, 2, nil)
876 if a == nil {
877 return nil
878 }
879 return a[0:2]
880 }
881
882
883
884
885
886
887 func (re *Regexp) FindSubmatch(b []byte) [][]byte {
888 var dstCap [4]int
889 a := re.doExecute(nil, b, "", 0, re.prog.NumCap, dstCap[:0])
890 if a == nil {
891 return nil
892 }
893 ret := make([][]byte, 1+re.numSubexp)
894 for i := range ret {
895 if 2*i < len(a) && a[2*i] >= 0 {
896 ret[i] = b[a[2*i]:a[2*i+1]:a[2*i+1]]
897 }
898 }
899 return ret
900 }
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919 func (re *Regexp) Expand(dst []byte, template []byte, src []byte, match []int) []byte {
920 return re.expand(dst, string(template), src, "", match)
921 }
922
923
924
925
926 func (re *Regexp) ExpandString(dst []byte, template string, src string, match []int) []byte {
927 return re.expand(dst, template, nil, src, match)
928 }
929
930 func (re *Regexp) expand(dst []byte, template string, bsrc []byte, src string, match []int) []byte {
931 for len(template) > 0 {
932 before, after, ok := strings.Cut(template, "$")
933 if !ok {
934 break
935 }
936 dst = append(dst, before...)
937 template = after
938 if template != "" && template[0] == '$' {
939
940 dst = append(dst, '$')
941 template = template[1:]
942 continue
943 }
944 name, num, rest, ok := extract(template)
945 if !ok {
946
947 dst = append(dst, '$')
948 continue
949 }
950 template = rest
951 if num >= 0 {
952 if 2*num+1 < len(match) && match[2*num] >= 0 {
953 if bsrc != nil {
954 dst = append(dst, bsrc[match[2*num]:match[2*num+1]]...)
955 } else {
956 dst = append(dst, src[match[2*num]:match[2*num+1]]...)
957 }
958 }
959 } else {
960 for i, namei := range re.subexpNames {
961 if name == namei && 2*i+1 < len(match) && match[2*i] >= 0 {
962 if bsrc != nil {
963 dst = append(dst, bsrc[match[2*i]:match[2*i+1]]...)
964 } else {
965 dst = append(dst, src[match[2*i]:match[2*i+1]]...)
966 }
967 break
968 }
969 }
970 }
971 }
972 dst = append(dst, template...)
973 return dst
974 }
975
976
977
978
979 func extract(str string) (name string, num int, rest string, ok bool) {
980 if str == "" {
981 return
982 }
983 brace := false
984 if str[0] == '{' {
985 brace = true
986 str = str[1:]
987 }
988 i := 0
989 for i < len(str) {
990 rune, size := utf8.DecodeRuneInString(str[i:])
991 if !unicode.IsLetter(rune) && !unicode.IsDigit(rune) && rune != '_' {
992 break
993 }
994 i += size
995 }
996 if i == 0 {
997
998 return
999 }
1000 name = str[:i]
1001 if brace {
1002 if i >= len(str) || str[i] != '}' {
1003
1004 return
1005 }
1006 i++
1007 }
1008
1009
1010 num = 0
1011 for i := 0; i < len(name); i++ {
1012 if name[i] < '0' || '9' < name[i] || num >= 1e8 {
1013 num = -1
1014 break
1015 }
1016 num = num*10 + int(name[i]) - '0'
1017 }
1018
1019 if name[0] == '0' && len(name) > 1 {
1020 num = -1
1021 }
1022
1023 rest = str[i:]
1024 ok = true
1025 return
1026 }
1027
1028
1029
1030
1031
1032
1033 func (re *Regexp) FindSubmatchIndex(b []byte) []int {
1034 return re.pad(re.doExecute(nil, b, "", 0, re.prog.NumCap, nil))
1035 }
1036
1037
1038
1039
1040
1041
1042 func (re *Regexp) FindStringSubmatch(s string) []string {
1043 var dstCap [4]int
1044 a := re.doExecute(nil, nil, s, 0, re.prog.NumCap, dstCap[:0])
1045 if a == nil {
1046 return nil
1047 }
1048 ret := make([]string, 1+re.numSubexp)
1049 for i := range ret {
1050 if 2*i < len(a) && a[2*i] >= 0 {
1051 ret[i] = s[a[2*i]:a[2*i+1]]
1052 }
1053 }
1054 return ret
1055 }
1056
1057
1058
1059
1060
1061
1062 func (re *Regexp) FindStringSubmatchIndex(s string) []int {
1063 return re.pad(re.doExecute(nil, nil, s, 0, re.prog.NumCap, nil))
1064 }
1065
1066
1067
1068
1069
1070
1071 func (re *Regexp) FindReaderSubmatchIndex(r io.RuneReader) []int {
1072 return re.pad(re.doExecute(r, nil, "", 0, re.prog.NumCap, nil))
1073 }
1074
1075 const startSize = 10
1076
1077
1078
1079
1080
1081 func (re *Regexp) FindAll(b []byte, n int) [][]byte {
1082 if n < 0 {
1083 n = len(b) + 1
1084 }
1085 var result [][]byte
1086 re.allMatches("", b, n, func(match []int) {
1087 if result == nil {
1088 result = make([][]byte, 0, startSize)
1089 }
1090 result = append(result, b[match[0]:match[1]:match[1]])
1091 })
1092 return result
1093 }
1094
1095
1096
1097
1098
1099 func (re *Regexp) FindAllIndex(b []byte, n int) [][]int {
1100 if n < 0 {
1101 n = len(b) + 1
1102 }
1103 var result [][]int
1104 re.allMatches("", b, n, func(match []int) {
1105 if result == nil {
1106 result = make([][]int, 0, startSize)
1107 }
1108 result = append(result, match[0:2])
1109 })
1110 return result
1111 }
1112
1113
1114
1115
1116
1117 func (re *Regexp) FindAllString(s string, n int) []string {
1118 if n < 0 {
1119 n = len(s) + 1
1120 }
1121 var result []string
1122 re.allMatches(s, nil, n, func(match []int) {
1123 if result == nil {
1124 result = make([]string, 0, startSize)
1125 }
1126 result = append(result, s[match[0]:match[1]])
1127 })
1128 return result
1129 }
1130
1131
1132
1133
1134
1135 func (re *Regexp) FindAllStringIndex(s string, n int) [][]int {
1136 if n < 0 {
1137 n = len(s) + 1
1138 }
1139 var result [][]int
1140 re.allMatches(s, nil, n, func(match []int) {
1141 if result == nil {
1142 result = make([][]int, 0, startSize)
1143 }
1144 result = append(result, match[0:2])
1145 })
1146 return result
1147 }
1148
1149
1150
1151
1152
1153 func (re *Regexp) FindAllSubmatch(b []byte, n int) [][][]byte {
1154 if n < 0 {
1155 n = len(b) + 1
1156 }
1157 var result [][][]byte
1158 re.allMatches("", b, n, func(match []int) {
1159 if result == nil {
1160 result = make([][][]byte, 0, startSize)
1161 }
1162 slice := make([][]byte, len(match)/2)
1163 for j := range slice {
1164 if match[2*j] >= 0 {
1165 slice[j] = b[match[2*j]:match[2*j+1]:match[2*j+1]]
1166 }
1167 }
1168 result = append(result, slice)
1169 })
1170 return result
1171 }
1172
1173
1174
1175
1176
1177 func (re *Regexp) FindAllSubmatchIndex(b []byte, n int) [][]int {
1178 if n < 0 {
1179 n = len(b) + 1
1180 }
1181 var result [][]int
1182 re.allMatches("", b, n, func(match []int) {
1183 if result == nil {
1184 result = make([][]int, 0, startSize)
1185 }
1186 result = append(result, match)
1187 })
1188 return result
1189 }
1190
1191
1192
1193
1194
1195 func (re *Regexp) FindAllStringSubmatch(s string, n int) [][]string {
1196 if n < 0 {
1197 n = len(s) + 1
1198 }
1199 var result [][]string
1200 re.allMatches(s, nil, n, func(match []int) {
1201 if result == nil {
1202 result = make([][]string, 0, startSize)
1203 }
1204 slice := make([]string, len(match)/2)
1205 for j := range slice {
1206 if match[2*j] >= 0 {
1207 slice[j] = s[match[2*j]:match[2*j+1]]
1208 }
1209 }
1210 result = append(result, slice)
1211 })
1212 return result
1213 }
1214
1215
1216
1217
1218
1219
1220 func (re *Regexp) FindAllStringSubmatchIndex(s string, n int) [][]int {
1221 if n < 0 {
1222 n = len(s) + 1
1223 }
1224 var result [][]int
1225 re.allMatches(s, nil, n, func(match []int) {
1226 if result == nil {
1227 result = make([][]int, 0, startSize)
1228 }
1229 result = append(result, match)
1230 })
1231 return result
1232 }
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251 func (re *Regexp) Split(s string, n int) []string {
1252
1253 if n == 0 {
1254 return nil
1255 }
1256
1257 if len(re.expr) > 0 && len(s) == 0 {
1258 return []string{""}
1259 }
1260
1261 matches := re.FindAllStringIndex(s, n)
1262 strings := make([]string, 0, len(matches))
1263
1264 beg := 0
1265 end := 0
1266 for _, match := range matches {
1267 if n > 0 && len(strings) >= n-1 {
1268 break
1269 }
1270
1271 end = match[0]
1272 if match[1] != 0 {
1273 strings = append(strings, s[beg:end])
1274 }
1275 beg = match[1]
1276 }
1277
1278 if end != len(s) {
1279 strings = append(strings, s[beg:])
1280 }
1281
1282 return strings
1283 }
1284
1285
1286
1287
1288
1289
1290
1291 func (re *Regexp) MarshalText() ([]byte, error) {
1292 return []byte(re.String()), nil
1293 }
1294
1295
1296
1297 func (re *Regexp) UnmarshalText(text []byte) error {
1298 newRE, err := Compile(string(text))
1299 if err != nil {
1300 return err
1301 }
1302 *re = *newRE
1303 return nil
1304 }
1305
View as plain text