golib/helper/str_helper.go
2023-09-25 23:49:59 +08:00

309 lines
7.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// str_helper.go
// Copyright (C) 2022 tiglog <me@tiglog.com>
//
// Distributed under terms of the MIT license.
//
package helper
import (
"math/rand"
"strings"
"time"
"unicode"
"git.hexq.cn/tiglog/golib/crypto/gmd5"
"github.com/rs/xid"
)
// 是否是字符串
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[:])
}
// 乱序字符串
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]
}
func GetCjkRange(code int) string {
var result string
if code >= 0x4E00 && code <= 0x9FFF {
result = "CJK"
} else if code >= 0x3400 && code <= 0x4DBF {
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"
} else if code >= 0x2EBF0 && code <= 0x2EE5D {
result = "EXT-I"
} else if code == 0x3007 {
result = "零"
} else if code >= 0x31C0 && code <= 0x31EF {
result = "笔画"
} else if code >= 0x2E80 && code <= 0x2EFF {
result = "部首补充"
} else if code >= 0xE000 && code <= 0xF8FF {
result = "PUA"
} else if code >= 0x2F00 && code <= 0x2FDF {
result = "康熙部首"
} else if code >= 0xF900 && code <= 0xFAD9 {
result = "兼容区"
} else if code >= 0xFE30 && code <= 0xFE4F {
result = "兼容形式"
} else if code >= 0x2F800 && code <= 0x2FA1D {
result = "兼容表意文字增补"
} else if code >= 0x3100 && code <= 0x312F {
result = "注音"
} else if code >= 0x17000 && code <= 0x187F7 {
result = "西夏文"
} else if code >= 0x18800 && code <= 0x18AFF {
result = "西夏文部首"
} else if code >= 0x18D00 && code <= 0x18D08 {
result = "西夏文增补"
} else if code >= 0x18B00 && code <= 0x18CFF {
result = "契丹文"
} else if code >= 0x0900 && code <= 0x097F {
result = "梵文"
} else if code >= 0x1B170 && code <= 0x1B2FF {
result = "女书"
} else if code >= 0x0F00 && code <= 0x0FFF {
result = "藏文"
} else if code >= 0x1800 && code <= 0x18AF {
result = "蒙古语"
} else if code >= 0x30A0 && code <= 0x30FF {
result = "日文片假名"
} else if code >= 0x31F0 && code <= 0x31FF {
result = "片假名扩展"
} else if code >= 0x3040 && code <= 0x309F {
result = "日文平假名"
} else if code >= 0x3000 && code <= 0x303F {
result = "符号和标点符号"
} else if code >= 0x2E00 && code <= 0x2E7F {
result = "补充标点符号"
} else if code >= 0x2200 && code <= 0x22FF {
result = "数学运算符号"
} else if code >= 0x2A00 && code <= 0x2AFF {
result = "补充数学运算符"
} else if code >= 0x2150 && code <= 0x218F {
result = "数字形式符号"
} else if code >= 0x2300 && code <= 0x23FF {
result = "杂项技术符号"
} else if code >= 0x27C0 && code <= 0x27EF {
result = "杂项数学符号-A"
} else if code >= 0x2980 && code <= 0x29FF {
result = "杂项数学符号-B"
} else if code >= 0x2190 && code <= 0x21FF {
result = "箭头符号"
} else if code >= 0x3190 && code <= 0x319F {
result = "汉文训读"
} else if code >= 0x3200 && code <= 0x32FF {
result = "带圈字符及月份"
} else if code >= 0x1F100 && code <= 0x1F1FF {
result = "带圈字母数字补充"
} else if code >= 0x1F200 && code <= 0x1F2FF {
result = "带圈表意文字补充"
} else if code >= 0x1D100 && code <= 0x1D1FF {
result = "音乐符号"
} else if code >= 0x1D360 && code <= 0x1D37F {
result = "算筹"
} else if code >= 0x1D300 && code <= 0x1D35F {
result = "太玄经符号"
} else if code >= 0x1F600 && code <= 0x1F64F {
result = "表情符号"
} else if code >= 0x2070 && code <= 0x209F {
result = "上下标"
} else if code >= 0x1D400 && code <= 0x1D7FF {
result = "字母和数字符号"
} else if code >= 0x25A0 && code <= 0x25FF {
result = "几何形状"
} else if code >= 0x1F780 && code <= 0x1F7FF {
result = "几何图形扩展"
} else if code >= 0x2630 && code <= 0x2637 {
result = "八卦"
} else if code >= 0x19904 && code <= 0x19967 {
result = "易经六十四卦符号"
} else if code >= 0x1FA00 && code <= 0x1FA6F {
result = "象棋符号"
} else if code >= 0x0370 && code <= 0x03FF {
result = "希腊语和科普特语"
} else if code >= 0x1F000 && code <= 0x1F02F {
result = "麻将牌"
} else if code >= 0x1F0A0 && code <= 0x1F0FF {
result = "扑克牌"
} else if code >= 0x20A0 && code <= 0x20CF {
result = "货币符号"
} else if code >= 0x1F680 && code <= 0x1F6FF {
result = "交通和地图符号"
} else if code >= 0x1F030 && code <= 0x1F09F {
result = "多米诺骨牌"
} else if code >= 0x1F300 && code <= 0x1F5FF {
result = "杂项符号和象形文字"
} else if code >= 0x2500 && code <= 0x257F {
result = "方框绘制字符"
} else if code >= 0x1F700 && code <= 0x1F77F {
result = "炼金术符号"
}
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))
}