-
Notifications
You must be signed in to change notification settings - Fork 191
/
split.go
202 lines (169 loc) · 4.78 KB
/
split.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
package strutil
import (
"regexp"
"strings"
)
// BeforeFirst get substring before first sep.
func BeforeFirst(s, sep string) string {
if i := strings.Index(s, sep); i >= 0 {
return s[:i]
}
return s
}
// AfterFirst get substring after first sep.
func AfterFirst(s, sep string) string {
if i := strings.Index(s, sep); i >= 0 {
return s[i+len(sep):]
}
return ""
}
// BeforeLast get substring before last sep.
func BeforeLast(s, sep string) string {
if i := strings.LastIndex(s, sep); i >= 0 {
return s[:i]
}
return s
}
// AfterLast get substring after last sep.
func AfterLast(s, sep string) string {
if i := strings.LastIndex(s, sep); i >= 0 {
return s[i+len(sep):]
}
return ""
}
/*************************************************************
* String split operation
*************************************************************/
// Cut same of the strings.Cut
func Cut(s, sep string) (before string, after string, found bool) {
if i := strings.Index(s, sep); i >= 0 {
return s[:i], s[i+len(sep):], true
}
return s, "", false
}
// QuietCut always returns two substring.
func QuietCut(s, sep string) (before string, after string) {
before, after, _ = Cut(s, sep)
return
}
// MustCut always returns two substring.
func MustCut(s, sep string) (before string, after string) {
var ok bool
before, after, ok = Cut(s, sep)
if !ok {
panic("cannot split input string to two nodes")
}
return
}
// TrimCut always returns two substring and trim space for items.
func TrimCut(s, sep string) (string, string) {
before, after, _ := Cut(s, sep)
return strings.TrimSpace(before), strings.TrimSpace(after)
}
// SplitKV split string to key and value.
func SplitKV(s, sep string) (string, string) { return TrimCut(s, sep) }
// SplitValid string to slice. will trim each item and filter empty string node.
func SplitValid(s, sep string) (ss []string) { return Split(s, sep) }
// Split string to slice. will trim each item and filter empty string node.
func Split(s, sep string) (ss []string) {
if s = strings.TrimSpace(s); s == "" {
return
}
for _, val := range strings.Split(s, sep) {
if val = strings.TrimSpace(val); val != "" {
ss = append(ss, val)
}
}
return
}
// SplitNValid string to slice. will filter empty string node.
func SplitNValid(s, sep string, n int) (ss []string) { return SplitN(s, sep, n) }
// SplitN string to slice. will filter empty string node.
func SplitN(s, sep string, n int) (ss []string) {
if s = strings.TrimSpace(s); s == "" {
return
}
rawList := strings.Split(s, sep)
for i, val := range rawList {
if val = strings.TrimSpace(val); val != "" {
if len(ss) == n-1 {
ss = append(ss, strings.TrimSpace(strings.Join(rawList[i:], sep)))
break
}
ss = append(ss, val)
}
}
return
}
// SplitTrimmed split string to slice.
// will trim space for each node, but not filter empty
func SplitTrimmed(s, sep string) (ss []string) {
if s = strings.TrimSpace(s); s == "" {
return
}
for _, val := range strings.Split(s, sep) {
ss = append(ss, strings.TrimSpace(val))
}
return
}
// SplitNTrimmed split string to slice.
// will trim space for each node, but not filter empty
func SplitNTrimmed(s, sep string, n int) (ss []string) {
if s = strings.TrimSpace(s); s == "" {
return
}
for _, val := range strings.SplitN(s, sep, n) {
ss = append(ss, strings.TrimSpace(val))
}
return
}
// 根据空白字符(空格,TAB,换行等)分隔字符串
var whitespaceRegexp = regexp.MustCompile("\\s+")
// SplitByWhitespace Separate strings by whitespace characters (space, TAB, newline, etc.)
func SplitByWhitespace(s string) []string {
return whitespaceRegexp.Split(s, -1)
}
// Substr for a string.
// if length <= 0, return pos to end.
func Substr(s string, pos, length int) string {
runes := []rune(s)
strLn := len(runes)
// pos is too large
if pos >= strLn {
return ""
}
stopIdx := pos + length
if length == 0 || stopIdx > strLn {
stopIdx = strLn
} else if length < 0 {
stopIdx = strLn + length
}
return string(runes[pos:stopIdx])
}
// SplitInlineComment for an inline text string.
func SplitInlineComment(val string, strict ...bool) (string, string) {
// strict check: must with space
if len(strict) > 0 && strict[0] {
if pos := strings.Index(val, " #"); pos > -1 {
return strings.TrimRight(val[0:pos], " "), val[pos+1:]
}
if pos := strings.Index(val, " //"); pos > -1 {
return strings.TrimRight(val[0:pos], " "), val[pos+1:]
}
} else {
if pos := strings.IndexByte(val, '#'); pos > -1 {
return strings.TrimRight(val[0:pos], " "), val[pos:]
}
if pos := strings.Index(val, "//"); pos > -1 {
return strings.TrimRight(val[0:pos], " "), val[pos:]
}
}
return val, ""
}
// FirstLine from command output
func FirstLine(output string) string {
if i := strings.IndexByte(output, '\n'); i >= 0 {
return output[0:i]
}
return output
}