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