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