github.com/whatap/golib@v0.0.22/util/stringutil/StringUtil.go (about) 1 package stringutil 2 3 import ( 4 "bufio" 5 "bytes" 6 "fmt" 7 "regexp" 8 "strconv" 9 "strings" 10 "unicode" 11 12 "golang.org/x/text/encoding/korean" 13 "golang.org/x/text/transform" 14 ) 15 16 func Tokenizer(src, delim string) []string { 17 if src == "" || delim == "" { 18 return []string{src} 19 } 20 chars := []rune(delim) 21 f := func(c rune) bool { 22 for i := 0; i < len(chars); i++ { 23 if chars[i] == c { 24 return true 25 } 26 } 27 return false 28 } 29 fields := strings.FieldsFunc(src, f) 30 return fields 31 } 32 func FirstWord(target, delim string) string { 33 if target == "" || delim == "" { 34 return target 35 } 36 37 out := Tokenizer(target, delim) 38 39 if len(out) >= 1 { 40 return strings.TrimSpace(out[0]) 41 } else { 42 return "" 43 } 44 } 45 func LastWord(target, delim string) string { 46 if target == "" || delim == "" { 47 return target 48 } 49 out := Tokenizer(target, delim) 50 51 if len(out) >= 1 { 52 return strings.TrimSpace(out[len(out)-1]) 53 } else { 54 return "" 55 } 56 } 57 func Cp949toUtf8(src []byte) string { 58 var b bytes.Buffer 59 wInUTF8 := transform.NewWriter(&b, korean.EUCKR.NewDecoder()) 60 wInUTF8.Write(src) 61 wInUTF8.Close() 62 return b.String() 63 } 64 65 // 2017.5.24 Java string.hashCode 함수 대체 66 func HashCode(s string) int { 67 h := 0 68 for i := 0; i < len(s); i++ { 69 h = 31*h + int(s[i]) 70 } 71 return h 72 } 73 74 func TrimEmpty(s string) string { 75 if s == "" { 76 return s 77 } else { 78 return strings.TrimSpace(s) 79 } 80 } 81 82 func Truncate(str string, length int) string { 83 if str == "" || len(str) <= length { 84 return str 85 } else { 86 return str[0:length] 87 } 88 } 89 90 func TruncateRune(str string, sz int) string { 91 if str == "" { 92 return str 93 } 94 sb := NewStringBuffer() 95 for i, ch := range str { 96 if i < sz { 97 sb.Append(string(ch)) 98 } 99 } 100 return sb.ToString() 101 } 102 103 // TODO Tckenizer, Split 테스트 필요 104 func Split(s, sep string) []string { 105 return strings.Split(s, sep) 106 } 107 108 // substring 109 func Substring(s string, from string, to string) string { 110 defer func() { 111 // recover 112 if r := recover(); r != nil { 113 //log.Println("recover:", r, string(debug.Stack())) 114 } 115 }() 116 pos := 0 117 pos1 := 0 118 119 pos = strings.Index(strings.ToLower(s), strings.ToLower(from)) 120 if pos < 0 { 121 return "" 122 } 123 pos += len(from) 124 125 if to != "" { 126 pos1 = strings.Index(strings.ToLower(s[pos:]), strings.ToLower(to)) 127 if pos1 < 0 { 128 pos1 = len(s) 129 } else { 130 pos1 = pos + pos1 131 } 132 } else { 133 pos1 = len(s) 134 } 135 136 return strings.TrimSpace(s[pos:pos1]) 137 } 138 139 // substring 140 func SubstringN(s string, from string, to string, n int) []string { 141 defer func() { 142 // recover 143 if r := recover(); r != nil { 144 //fmt.Println("recover:", r, string(debug.Stack())) 145 } 146 }() 147 result := make([]string, 0) 148 149 lastPos := 0 150 pos := 0 151 pos1 := 0 152 idx := 0 153 for pos = strings.Index(strings.ToLower(s), strings.ToLower(from)); pos >= 0; pos = strings.Index(strings.ToLower(s[lastPos:]), strings.ToLower(from)) { 154 if pos < 0 { 155 break 156 } 157 pos += len(from) 158 159 if to != "" { 160 pos1 = strings.Index(strings.ToLower(s[lastPos+pos:]), strings.ToLower(to)) 161 if pos1 < 0 { 162 pos1 = len(s) 163 } else { 164 pos1 = pos + pos1 165 } 166 } else { 167 pos1 = len(s) 168 } 169 170 str := strings.TrimSpace(s[lastPos+pos : lastPos+pos1]) 171 result = append(result, str) 172 173 lastPos = lastPos + pos1 + len(to) 174 idx++ 175 176 if n != -1 && idx >= n { 177 break 178 } 179 180 if lastPos >= len(s) { 181 break 182 } 183 } 184 return result 185 } 186 187 // substring Prefix "abcd efg hijk" from[]{"a","e","h"} => result[]{"abcd", "efg", "hijk"} 188 func SubstringWords(s string, from []string) map[string]string { 189 defer func() { 190 // recover 191 if r := recover(); r != nil { 192 //log.Println("recover:", r, string(debug.Stack())) 193 } 194 }() 195 result := make(map[string]string) 196 //result := make([]string, 0) 197 198 lastPos := 0 199 pos := -1 200 pos1 := -1 201 202 for i, it := range from { 203 pos = strings.Index(strings.ToLower(s[lastPos:]), strings.ToLower(it)) 204 if i == 0 { 205 pos1 = pos 206 } else { 207 if pos1 > -1 && pos > pos1 { 208 str := strings.TrimSpace(s[pos1:pos]) 209 //result = append(result, str) 210 result[it] = str 211 212 pos1 = pos 213 } 214 } 215 } 216 217 return result 218 } 219 220 // get k, v 221 func ToPair(s string, sep string) (k, v string) { 222 pos := 0 223 pos = strings.Index(strings.ToLower(s), strings.ToLower(sep)) 224 if pos != -1 { 225 k = s[0:pos] 226 v = s[pos+len(sep):] 227 } else { 228 k = "" 229 v = "" 230 } 231 232 return strings.TrimSpace(k), strings.TrimSpace(v) 233 } 234 func LPad(str string, n int) string { 235 if str == "" { 236 return padding(n, " ") 237 } 238 slen := len(str) 239 if slen >= n { 240 return str 241 } 242 return padding(n-slen, " ") + str 243 } 244 func RPad(str string, n int) string { 245 if str == "" { 246 return padding(n, " ") 247 } 248 slen := len(str) 249 if slen >= n { 250 return str 251 } 252 return str + padding(n-slen, " ") 253 } 254 func padding(n int, ch string) string { 255 buf := bytes.Buffer{} 256 for i := 0; i < n; i++ { 257 buf.WriteString(ch) 258 } 259 return buf.String() 260 } 261 func IsNotEmpty(s string) bool { 262 if s == "" { 263 return false 264 } else { 265 return true 266 } 267 } 268 func LPadInt(v, size int) string { 269 var ret string 270 ret = fmt.Sprintf("%d", v) 271 if len(ret) > size { 272 return ret 273 } 274 return padding(size-len(ret), "0") + ret 275 } 276 func CutLastString(className string, delim string) string { 277 x := strings.LastIndex(className, delim) 278 if x >= 0 { 279 return className[x+1:] 280 } 281 return className 282 } 283 284 func StringInSlice(a string, list []string) bool { 285 for _, b := range list { 286 if b == a { 287 return true 288 } 289 } 290 return false 291 } 292 293 var linuxPattern = regexp.MustCompile(`\\[0-9]{3}`) 294 295 func EscapeSpace(a string) string { 296 for _, m := range linuxPattern.FindAllString(a, -1) { 297 b := m[1:] 298 i, err := strconv.ParseInt(b, 8, 32) 299 if err == nil { 300 c := fmt.Sprintf("%c", i) 301 a = strings.Replace(a, m, c, -1) 302 } 303 } 304 305 return a 306 } 307 308 func NullTermToStrings(b []byte) (s []string) { 309 for { 310 i := bytes.IndexByte(b, byte(0)) 311 if i == -1 { 312 break 313 } 314 s = append(s, string(b[0:i])) 315 b = b[i+1:] 316 if b[0] == byte(0) { 317 break 318 } 319 } 320 return 321 } 322 323 func Contains(tokens []string, src string) (ret bool) { 324 ret = false 325 for _, t := range tokens { 326 if t == src { 327 ret = true 328 329 return 330 } 331 } 332 333 return 334 } 335 func TrimAllSpace(str string) string { 336 rd := bufio.NewReader(strings.NewReader(str)) 337 var buf bytes.Buffer 338 for { 339 if r, _, err := rd.ReadRune(); err == nil { 340 if !unicode.IsSpace(r) { 341 buf.WriteRune(r) 342 } 343 } else { 344 break 345 } 346 } 347 return buf.String() 348 } 349 350 func ParseInt32(str string) int32 { 351 if r, err := strconv.ParseInt(str, 10, 32); err == nil { 352 return int32(r) 353 } else { 354 return 0 355 } 356 } 357 358 func ParseInt64(str string) int64 { 359 if r, err := strconv.ParseInt(str, 10, 64); err == nil { 360 return int64(r) 361 } else { 362 return 0 363 } 364 } 365 func ParseStringZeroToEmpty(v int64) string { 366 if v == 0 { 367 return "" 368 } else { 369 return fmt.Sprintf("%d", v) 370 } 371 } 372 373 func Concat(v ...interface{}) string { 374 var b bytes.Buffer 375 for _, it := range v { 376 switch it.(type) { 377 case int: 378 b.WriteString(strconv.FormatInt(int64(it.(int)), 10)) 379 case int32: 380 b.WriteString(strconv.FormatInt(int64(it.(int32)), 10)) 381 case int64: 382 b.WriteString(strconv.FormatInt(it.(int64), 10)) 383 case uint: 384 b.WriteString(strconv.FormatUint(uint64(it.(uint)), 10)) 385 case uint32: 386 b.WriteString(strconv.FormatUint(uint64(it.(uint32)), 10)) 387 case uint64: 388 b.WriteString(strconv.FormatUint(it.(uint64), 10)) 389 case float32: 390 b.WriteString(strconv.FormatFloat(float64(it.(float32)), 'f', 2, 64)) 391 case float64: 392 b.WriteString(strconv.FormatFloat(it.(float64), 'f', 2, 64)) 393 case string: 394 b.WriteString(it.(string)) 395 } 396 } 397 return b.String() 398 } 399 400 func ParseMapSASToString(m map[string][]string, maxCount, keyMaxSize, valueMaxSize int) string { 401 var rt string 402 sb := NewStringBuffer() 403 if m != nil && len(m) > 0 { 404 idx := 0 405 for k, v := range m { 406 if idx > maxCount { 407 break 408 } 409 sb.Append(Truncate(k, keyMaxSize)).Append("=") 410 if len(v) > 0 { 411 sb.AppendLine(Truncate(v[0], valueMaxSize)) 412 } 413 } 414 rt = sb.ToString() 415 sb.Clear() 416 } 417 return rt 418 } 419 420 func ArrayInt16ToString(a []int16, sep string) string { 421 if len(a) == 0 { 422 return "" 423 } 424 425 b := make([]string, len(a)) 426 for i, v := range a { 427 b[i] = strconv.Itoa(int(v)) 428 } 429 return strings.Join(b, sep) 430 } 431 432 func InArray(str string, list []string) bool { 433 for _, it := range list { 434 if strings.ToUpper(strings.TrimSpace(str)) == strings.ToUpper(strings.TrimSpace(it)) { 435 return true 436 } 437 } 438 return false 439 } 440 441 func InArrayCaseSensitive(str string, list []string) bool { 442 for _, it := range list { 443 if strings.TrimSpace(str) == strings.TrimSpace(it) { 444 return true 445 } 446 } 447 return false 448 }