golib/helper/str_helper.go

207 lines
4.0 KiB
Go
Raw Normal View History

2023-06-15 21:22:51 +08:00
//
// str_helper.go
// Copyright (C) 2022 tiglog <me@tiglog.com>
//
// Distributed under terms of the MIT license.
//
package helper
import (
"math/rand"
"strings"
2023-06-15 21:22:51 +08:00
"time"
"unicode"
2023-06-15 21:38:12 +08:00
"git.hexq.cn/tiglog/golib/crypto/gmd5"
"github.com/rs/xid"
2023-06-15 21:22:51 +08:00
)
// 是否是字符串
func IsString(v interface{}) bool {
_, ok := v.(string)
return ok
}
// 随机字符串
func RandString(n int) string {
letterRunes := []rune("1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
rand.Seed(time.Now().UnixNano())
b := make([]rune, n)
for i := range b {
b[i] = letterRunes[rand.Intn(len(letterRunes))]
}
return string(b)
}
// 首字母大写
func UcFirst(str string) string {
for _, v := range str {
u := string(unicode.ToUpper(v))
return u + str[len(u):]
}
return ""
}
// 首字母小写
func LcFirst(str string) string {
for _, v := range str {
u := string(unicode.ToLower(v))
return u + str[len(u):]
}
return ""
}
// 驼峰转蛇形, XxYy => xx_yy
func SnakeString(str string) string {
data := make([]byte, 0, len(str)*2)
j := false
num := len(str)
for i := 0; i < num; i++ {
d := str[i]
if i > 0 && d >= 'A' && d <= 'Z' && j {
data = append(data, '_')
}
if d != '_' {
j = true
}
data = append(data, d)
}
return strings.ToLower(string(data[:]))
}
// 蛇形转驼峰, xx_yy => XxYy
func CamelString(str string) string {
data := make([]byte, 0, len(str))
j := false
k := false
num := len(str) - 1
for i := 0; i <= num; i++ {
d := str[i]
if k == false && d >= 'A' && d <= 'Z' {
k = true
}
if d >= 'a' && d <= 'z' && (j || k == false) {
d = d - 32
j = false
k = true
}
if k && d == '_' && num > i && str[i+1] >= 'a' && str[i+1] <= 'z' {
j = true
continue
}
data = append(data, d)
}
return string(data[:])
}
2023-06-15 21:22:51 +08:00
// 乱序字符串
func Shuffle(str string) string {
if str == "" {
return str
}
runes := []rune(str)
index := 0
for i := len(runes) - 1; i > 0; i-- {
index = rand.Intn(i + 1)
if i != index {
runes[i], runes[index] = runes[index], runes[i]
}
}
return string(runes)
}
// 反序字符串
func Reverse(str string) string {
n := len(str)
runes := make([]rune, n)
for _, r := range str {
n--
runes[n] = r
}
return string(runes[n:])
}
// 唯一字符串
// 返回字符串长度为 20
func GenId() string {
guid := xid.New()
return guid.String()
}
// 可变长度的唯一字符串
// 长度太短,可能就不唯一了
// 长度大于等于 16 为最佳
// 长度小于20时为 GenId 的值 md5 后的前缀因此理论上前6位也能在大多数情况
// 下唯一
func Uniq(l int) string {
if l <= 0 {
panic("wrong length param")
}
ret := GenId()
hl := len(ret)
if l < hl {
t, err := gmd5.EncryptString(ret)
if err != nil {
return ret[hl-l:]
}
return t[:l]
}
mhac_len := 6
pl := len(ret)
var hash string
for l > pl {
hash = GenId()
hash = hash[mhac_len:]
ret += hash
pl += len(hash)
}
// log.Println("ret=", ret, ", pl=", pl, ", l=", l)
return ret[0:l]
}
2023-09-20 16:49:31 +08:00
func GetCjkRange(code int) string {
var result string
2023-09-21 20:56:57 +08:00
if code >= 0x4E00 && code <= 0x9FFF {
result = "CJK"
} else if code >= 0x3400 && code <= 0x4DBF {
2023-09-20 16:49:31 +08:00
result = "EXT-A"
} else if code >= 0x20000 && code <= 0x2A6DF {
result = "EXT-B"
} else if code >= 0x2A700 && code <= 0x2B739 {
result = "EXT-C"
} else if code >= 0x2B740 && code <= 0x2B81D {
result = "EXT-D"
} else if code >= 0x2B820 && code <= 0x2CEA1 {
result = "EXT-E"
} else if code >= 0x2CEB0 && code <= 0x2EBE0 {
result = "EXT-F"
} else if code >= 0x30000 && code <= 0x3134A {
result = "EXT-G"
} else if code >= 0x31350 && code <= 0x323AF {
result = "EXT-H"
2023-09-21 20:56:57 +08:00
} else if code >= 0x2EBF0 && code <= 0x2EE5D {
result = "EXT-I"
} else if code == 0x3007 {
result = "零"
2023-09-20 16:49:31 +08:00
} else if code >= 0xE000 && code <= 0xF8FF {
result = "PUA"
}
return result
}
// 获取某个字的 unicode 值
func Ord(in string) int {
s := []rune(in)
return int(s[0])
}
// 把 unicode 值转成字符串
func Chr(code int) string {
return string(rune(code))
}