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