Source file
src/strings/iter.go
1
2
3
4
5 package strings
6
7 import (
8 "iter"
9 "unicode"
10 "unicode/utf8"
11 )
12
13
14
15
16
17
18 func Lines(s string) iter.Seq[string] {
19 return func(yield func(string) bool) {
20 for len(s) > 0 {
21 var line string
22 if i := IndexByte(s, '\n'); i >= 0 {
23 line, s = s[:i+1], s[i+1:]
24 } else {
25 line, s = s, ""
26 }
27 if !yield(line) {
28 return
29 }
30 }
31 }
32 }
33
34
35 func explodeSeq(s string, yield func(string) bool) {
36 for len(s) > 0 {
37 _, size := utf8.DecodeRuneInString(s)
38 if !yield(s[:size]) {
39 return
40 }
41 s = s[size:]
42 }
43 }
44
45
46
47 func splitSeq(s, sep string, sepSave int) iter.Seq[string] {
48 return func(yield func(string) bool) {
49 if len(sep) == 0 {
50 explodeSeq(s, yield)
51 return
52 }
53 for {
54 i := Index(s, sep)
55 if i < 0 {
56 break
57 }
58 frag := s[:i+sepSave]
59 if !yield(frag) {
60 return
61 }
62 s = s[i+len(sep):]
63 }
64 yield(s)
65 }
66 }
67
68
69
70
71
72 func SplitSeq(s, sep string) iter.Seq[string] {
73 return splitSeq(s, sep, 0)
74 }
75
76
77
78
79
80 func SplitAfterSeq(s, sep string) iter.Seq[string] {
81 return splitSeq(s, sep, len(sep))
82 }
83
84
85
86
87
88 func FieldsSeq(s string) iter.Seq[string] {
89 return func(yield func(string) bool) {
90 start := -1
91 for i := 0; i < len(s); {
92 size := 1
93 r := rune(s[i])
94 isSpace := asciiSpace[s[i]] != 0
95 if r >= utf8.RuneSelf {
96 r, size = utf8.DecodeRuneInString(s[i:])
97 isSpace = unicode.IsSpace(r)
98 }
99 if isSpace {
100 if start >= 0 {
101 if !yield(s[start:i]) {
102 return
103 }
104 start = -1
105 }
106 } else if start < 0 {
107 start = i
108 }
109 i += size
110 }
111 if start >= 0 {
112 yield(s[start:])
113 }
114 }
115 }
116
117
118
119
120
121 func FieldsFuncSeq(s string, f func(rune) bool) iter.Seq[string] {
122 return func(yield func(string) bool) {
123 start := -1
124 for i := 0; i < len(s); {
125 size := 1
126 r := rune(s[i])
127 if r >= utf8.RuneSelf {
128 r, size = utf8.DecodeRuneInString(s[i:])
129 }
130 if f(r) {
131 if start >= 0 {
132 if !yield(s[start:i]) {
133 return
134 }
135 start = -1
136 }
137 } else if start < 0 {
138 start = i
139 }
140 i += size
141 }
142 if start >= 0 {
143 yield(s[start:])
144 }
145 }
146 }
147
View as plain text