Commit 6cc94a06e9fe55808badb616b9e8605ba275a7a4
1 parent
5d0856f6f3
Exists in
master
cleanup
Showing
1 changed file
with
16 additions
and
23 deletions
Show diff stats
string_util.go
1 | package webutility | 1 | package webutility |
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "fmt" | 4 | "fmt" |
5 | "strconv" | 5 | "strconv" |
6 | "strings" | 6 | "strings" |
7 | "unicode" | 7 | "unicode" |
8 | |||
9 | "golang.org/x/exp/utf8string" | ||
8 | ) | 10 | ) |
9 | 11 | ||
10 | const sanitisationPatern = "\"';&*<>=\\`:" | 12 | const sanitisationPatern = "\"';&*<>=\\`:" |
11 | 13 | ||
12 | // SanitiseString removes characters from s found in patern and returns new modified string. | 14 | // SanitiseString removes characters from s found in patern and returns new modified string. |
13 | func SanitiseString(s string) string { | 15 | func SanitiseString(s string) string { |
14 | return ReplaceAny(s, sanitisationPatern, "") | 16 | return ReplaceAny(s, sanitisationPatern, "") |
15 | } | 17 | } |
16 | 18 | ||
17 | // IsWrappedWith ... | 19 | // IsWrappedWith ... |
18 | func IsWrappedWith(src, begin, end string) bool { | 20 | func IsWrappedWith(src, begin, end string) bool { |
19 | return strings.HasPrefix(src, begin) && strings.HasSuffix(src, end) | 21 | return strings.HasPrefix(src, begin) && strings.HasSuffix(src, end) |
20 | } | 22 | } |
21 | 23 | ||
22 | // ParseInt64Arr ... | 24 | // ParseInt64Arr ... |
23 | func ParseInt64Arr(s, sep string) (arr []int64) { | 25 | func ParseInt64Arr(s, sep string) (arr []int64) { |
24 | s = strings.TrimSpace(s) | 26 | s = strings.TrimSpace(s) |
25 | if s == "" { | 27 | if s == "" { |
26 | return | 28 | return |
27 | } | 29 | } |
28 | parts := strings.Split(s, sep) | 30 | parts := strings.Split(s, sep) |
29 | arr = make([]int64, len(parts)) | 31 | arr = make([]int64, len(parts)) |
30 | for i, p := range parts { | 32 | for i, p := range parts { |
31 | num := StringToInt64(p) | 33 | num := StringToInt64(p) |
32 | arr[i] = num | 34 | arr[i] = num |
33 | } | 35 | } |
34 | 36 | ||
35 | return arr | 37 | return arr |
36 | } | 38 | } |
37 | 39 | ||
38 | // Int64SliceToString ... | 40 | // Int64SliceToString ... |
39 | func Int64SliceToString(arr []int64) (s string) { | 41 | func Int64SliceToString(arr []int64) (s string) { |
40 | if len(arr) == 0 { | 42 | if len(arr) == 0 { |
41 | return "" | 43 | return "" |
42 | } | 44 | } |
43 | 45 | ||
44 | s += fmt.Sprintf("%d", arr[0]) | 46 | s += fmt.Sprintf("%d", arr[0]) |
45 | for i := 1; i < len(arr); i++ { | 47 | for i := 1; i < len(arr); i++ { |
46 | s += fmt.Sprintf(",%d", arr[i]) | 48 | s += fmt.Sprintf(",%d", arr[i]) |
47 | } | 49 | } |
48 | 50 | ||
49 | return s | 51 | return s |
50 | } | 52 | } |
51 | 53 | ||
52 | // CombineStrings ... | 54 | // CombineStrings ... |
53 | func CombineStrings(s1, s2, s3 string) string { | 55 | func CombineStrings(s1, s2, s3 string) string { |
54 | s1 = strings.TrimSpace(s1) | 56 | s1 = strings.TrimSpace(s1) |
55 | s2 = strings.TrimSpace(s2) | 57 | s2 = strings.TrimSpace(s2) |
56 | 58 | ||
57 | if s1 != "" && s2 != "" { | 59 | if s1 != "" && s2 != "" { |
58 | s1 += s3 + s2 | 60 | s1 += s3 + s2 |
59 | } else { | 61 | } else { |
60 | s1 += s2 | 62 | s1 += s2 |
61 | } | 63 | } |
62 | 64 | ||
63 | return s1 | 65 | return s1 |
64 | } | 66 | } |
65 | 67 | ||
66 | // ReplaceAny replaces any of the characters from patern found in s with r and returns a new resulting string. | 68 | // ReplaceAny replaces any of the characters from patern found in s with r and returns a new resulting string. |
67 | func ReplaceAny(s, patern, r string) (n string) { | 69 | func ReplaceAny(s, patern, r string) (n string) { |
68 | n = s | 70 | n = s |
69 | for _, c := range patern { | 71 | for _, c := range patern { |
70 | n = strings.Replace(n, string(c), r, -1) | 72 | n = strings.Replace(n, string(c), r, -1) |
71 | } | 73 | } |
72 | return n | 74 | return n |
73 | } | 75 | } |
74 | 76 | ||
75 | // StringToBool ... | 77 | // StringToBool ... |
76 | func StringToBool(s string) bool { | 78 | func StringToBool(s string) bool { |
77 | res, _ := strconv.ParseBool(s) | 79 | res, _ := strconv.ParseBool(s) |
78 | return res | 80 | return res |
79 | } | 81 | } |
80 | 82 | ||
81 | // BoolToString ... | 83 | // BoolToString ... |
82 | func BoolToString(b bool) string { | 84 | func BoolToString(b bool) string { |
83 | return fmt.Sprintf("%b", b) | 85 | return fmt.Sprintf("%b", b) |
84 | } | 86 | } |
85 | 87 | ||
86 | // StringSliceContains ... | 88 | // StringSliceContains ... |
87 | func StringSliceContains(slice []string, s string) bool { | 89 | func StringSliceContains(slice []string, s string) bool { |
88 | for i := range slice { | 90 | for i := range slice { |
89 | if slice[i] == s { | 91 | if slice[i] == s { |
90 | return true | 92 | return true |
91 | } | 93 | } |
92 | } | 94 | } |
93 | return false | 95 | return false |
94 | } | 96 | } |
95 | 97 | ||
96 | func SplitString(s, sep string) (res []string) { | 98 | func SplitString(s, sep string) (res []string) { |
97 | parts := strings.Split(s, sep) | 99 | parts := strings.Split(s, sep) |
98 | for _, p := range parts { | 100 | for _, p := range parts { |
99 | if p != "" { | 101 | if p != "" { |
100 | res = append(res, p) | 102 | res = append(res, p) |
101 | } | 103 | } |
102 | } | 104 | } |
103 | return res | 105 | return res |
104 | } | 106 | } |
105 | 107 | ||
106 | // StringAt ... | 108 | // StringAt ... |
107 | func StringAt(s string, index int) string { | 109 | func StringAt(s string, index int) string { |
108 | if len(s)-1 < index || index < 0 { | 110 | if len(s)-1 < index || index < 0 { |
109 | return "" | 111 | return "" |
110 | } | 112 | } |
111 | 113 | ||
112 | return string(s[index]) | 114 | return string(s[index]) |
113 | } | 115 | } |
114 | 116 | ||
117 | func StringAtRune(s string, index int) string { | ||
118 | str := utf8string.NewString(s) | ||
119 | max := str.RuneCount() | ||
120 | if index < max { | ||
121 | return string(str.At(index)) | ||
122 | } | ||
123 | return "" | ||
124 | } | ||
125 | |||
115 | // SplitText ... | 126 | // SplitText ... |
116 | func SplitText(s string, maxLen int) (lines []string) { | 127 | func SplitText(s string, maxLen int) (lines []string) { |
117 | runes := []rune(s) | 128 | runes := []rune(s) |
118 | 129 | ||
119 | i, start, sep, l := 0, 0, 0, 0 | 130 | i, start, sep, l := 0, 0, 0, 0 |
120 | for i = 0; i < len(runes); i++ { | 131 | for i = 0; i < len(runes); i++ { |
121 | c := runes[i] | 132 | c := runes[i] |
122 | 133 | ||
123 | if unicode.IsSpace(c) { | 134 | if unicode.IsSpace(c) { |
124 | sep = i | 135 | sep = i |
125 | } | 136 | } |
126 | 137 | ||
127 | if c == '\n' { | 138 | if c == '\n' { |
128 | if start != sep { | 139 | if start != sep { |
129 | lines = append(lines, string(runes[start:sep])) | 140 | lines = append(lines, string(runes[start:sep])) |
130 | } | 141 | } |
131 | start = i | 142 | start = i |
132 | sep = i | 143 | sep = i |
133 | l = 0 | 144 | l = 0 |
134 | } else if l >= maxLen { | 145 | } else if l >= maxLen { |
135 | if start != sep { | 146 | if start != sep { |
136 | lines = append(lines, string(runes[start:sep])) | 147 | lines = append(lines, string(runes[start:sep])) |
137 | sep = i | 148 | sep = i |
138 | start = i - 1 | 149 | start = i - 1 |
139 | l = 0 | 150 | l = 0 |
140 | } | 151 | } |
141 | } else { | 152 | } else { |
142 | l++ | 153 | l++ |
143 | } | 154 | } |
144 | } | 155 | } |
145 | if start != i-1 { | 156 | if start != i-1 { |
146 | lines = append(lines, string(runes[start:i-1])) | 157 | lines = append(lines, string(runes[start:i-1])) |
147 | } | 158 | } |
148 | 159 | ||
149 | return lines | 160 | return lines |
150 | } | 161 | } |
151 | 162 | ||
152 | func CutTextWithThreeDots(txt string, maxLen int) string { | 163 | func CutTextWith(txt string, maxLen int, tail string) string { |
153 | if len(txt) < maxLen || len(txt) <= 3 { | 164 | if len(txt) < maxLen || len(txt) <= len(tail) { |
154 | return txt | ||
155 | } | ||
156 | |||
157 | return txt[:maxLen-3] + "..." | ||
158 | } | ||
159 | |||
160 | const threeDots = "\u2056\u2056\u2056" | ||
161 | |||
162 | func LimitTextWithThreeDots(txt string, maxLen int) string { | ||
163 | if len(txt) <= maxLen { | ||
164 | return txt | ||
165 | } | ||
166 | |||
167 | return txt[:maxLen] + threeDots | ||
168 | } | ||
169 | |||
170 | func LimitMSWordTextWithThreeDots(txt string, maxLen int) string { | ||
171 | if len(txt) <= maxLen { | ||
172 | return txt | 165 | return txt |
173 | } | 166 | } |
174 | 167 | ||
175 | return txt[:maxLen] + "..." | 168 | return txt[:maxLen-3] + tail |
176 | } | 169 | } |
177 | 170 | ||
178 | func ThreeDots(txt string, maxLen int) string { | 171 | func LimitTextWith(txt string, maxLen int, tail string) string { |
179 | if len(txt) <= maxLen { | 172 | if len(txt) <= maxLen { |
180 | return txt | 173 | return txt |
181 | } | 174 | } |
182 | 175 | ||
183 | return txt[:maxLen] + "..." | 176 | return txt[:maxLen] + tail |
184 | } | 177 | } |
185 | 178 | ||
186 | // SplitStringAtWholeWords ... | 179 | // SplitStringAtWholeWords ... |
187 | func SplitStringAtWholeWords(s string, maxLen int) (res []string) { | 180 | func SplitStringAtWholeWords(s string, maxLen int) (res []string) { |
188 | parts := strings.Split(s, " ") | 181 | parts := strings.Split(s, " ") |
189 | 182 | ||
190 | res = append(res, parts[0]) | 183 | res = append(res, parts[0]) |
191 | i := 0 | 184 | i := 0 |
192 | for j := 1; j < len(parts); j++ { | 185 | for j := 1; j < len(parts); j++ { |
193 | p := strings.TrimSpace(parts[j]) | 186 | p := strings.TrimSpace(parts[j]) |
194 | if len(p) > maxLen { | 187 | if len(p) > maxLen { |
195 | // TODO(marko): check if maxLen is >= 3 | 188 | // TODO(marko): check if maxLen is >= 3 |
196 | p = p[0 : maxLen-3] | 189 | p = p[0 : maxLen-3] |
197 | p += "..." | 190 | p += "..." |
198 | } | 191 | } |
199 | if len(res[i])+len(p)+1 <= maxLen { | 192 | if len(res[i])+len(p)+1 <= maxLen { |
200 | res[i] += " " + p | 193 | res[i] += " " + p |
201 | } else { | 194 | } else { |
202 | res = append(res, p) | 195 | res = append(res, p) |
203 | i++ | 196 | i++ |
204 | } | 197 | } |
205 | } | 198 | } |
206 | 199 | ||
207 | return res | 200 | return res |
208 | } | 201 | } |
209 | 202 | ||
210 | // StringToInt64 ... | 203 | // StringToInt64 ... |
211 | func StringToInt64(s string) int64 { | 204 | func StringToInt64(s string) int64 { |
212 | i, _ := strconv.ParseInt(s, 10, 64) | 205 | i, _ := strconv.ParseInt(s, 10, 64) |
213 | return i | 206 | return i |
214 | } | 207 | } |
215 | 208 | ||
216 | // StringToFloat64 ... | 209 | // StringToFloat64 ... |
217 | func StringToFloat64(s string) float64 { | 210 | func StringToFloat64(s string) float64 { |
218 | f, _ := strconv.ParseFloat(s, 64) | 211 | f, _ := strconv.ParseFloat(s, 64) |