Files
4566704 d13de8f3fa feat(stringx): 自 go-hua/common 迁入字符串/切片/拼音工具并独立成包
- common 的 string.go/array.go/pinyin.go 拆为 stringx 包(含随机串、GUID、
  通配符匹配、校验规则、链式缓冲、驼峰转下划线、切片删元素、拼音首字母)
- 附单元测试与 examples/stringx 可运行例程、包 README
- go.mod 新增直接依赖 mozillazg/go-pinyin(go-hua 同版本锁 v0.20.0→实际解析 v0.21.0)
2026-09-20 12:20:28 +08:00

258 lines
5.9 KiB
Go
Raw Permalink 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.
// Package stringx 字符串与切片通用工具:随机串、UUID、通配符匹配、中间串提取、
// 手机号/身份证校验、链式字节缓冲、驼峰转下划线、切片删元素、中文拼音首字母。
package stringx
import (
"bytes"
"crypto/rand"
"fmt"
"log"
"math/big"
"regexp"
"strconv"
"strings"
"unicode"
)
// CreateRandomString 生成指定长度的随机字符串(含大小写字母与数字)
func CreateRandomString(len int) string {
var container string
var str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
b := bytes.NewBufferString(str)
length := b.Len()
bigInt := big.NewInt(int64(length))
for i := 0; i < len; i++ {
randomInt, _ := rand.Int(rand.Reader, bigInt)
container += string(str[randomInt.Int64()])
}
return container
}
// CreateRandomStringHex 生成指定长度的随机字符串(十六进制字符)
func CreateRandomStringHex(len int) string {
var container string
var str = "ABCDEF1234567890"
b := bytes.NewBufferString(str)
length := b.Len()
bigInt := big.NewInt(int64(length))
for i := 0; i < len; i++ {
randomInt, _ := rand.Int(rand.Reader, bigInt)
container += string(str[randomInt.Int64()])
}
return container
}
// CreateRandomStringInt 生成指定长度的纯数字随机字符串
func CreateRandomStringInt(len int) string {
var container string
var str = "1234567890"
b := bytes.NewBufferString(str)
length := b.Len()
bigInt := big.NewInt(int64(length))
for i := 0; i < len; i++ {
randomInt, _ := rand.Int(rand.Reader, bigInt)
container += string(str[randomInt.Int64()])
}
return container
}
// IsMatchDynamic 动态规划;时间复杂度O(n^2),空间复杂度O(n^2)
func IsMatchDynamic(s string, p string) bool {
n, m := len(s), len(p)
dp := make([][]bool, n+1)
for i := 0; i <= n; i++ {
dp[i] = make([]bool, m+1)
}
dp[0][0] = true
for i := 1; i <= m; i++ {
if p[i-1] == '*' {
// 可以匹配任意字符串(包括空字符串)
dp[0][i] = true
} else {
break
}
}
for i := 1; i <= n; i++ {
for j := 1; j <= m; j++ {
if p[j-1] == '*' {
// dp[i][j-1]=>不使用这个*,dp[i-1][j]=>使用这个*
dp[i][j] = dp[i][j-1] || dp[i-1][j]
} else if p[j-1] == '?' || s[i-1] == p[j-1] {
dp[i][j] = dp[i-1][j-1]
}
}
}
return dp[n][m]
}
// IsMatchGreed 贪心;时间复杂度O(n^2),空间复杂度O(1)
func IsMatchGreed(s string, p string) bool {
i, j := 0, 0
start, last := 0, 0
for i = 0; i < len(s); {
if j < len(p) && (s[i] == p[j] || p[j] == '?') {
i++
j++
} else if j < len(p) && p[j] == '*' {
last = i
// 记录s下一个的位置
start = j + 1
// 记录*下一个的位置
j++
} else if start != 0 {
last++
i = last
// 更新到s记录位置的下一个
j = start
} else {
return false
}
}
for ; j < len(p) && p[j] == '*'; j++ {
}
return j == len(p)
}
// GetBetweenStr 取中间字符串
func GetBetweenStr(str, starting, ending string) string {
s := strings.Index(str, starting)
if s < 0 {
return ""
}
s += len(starting)
if ending == "" {
return str[s:]
}
e := strings.Index(str[s:], ending)
if e < 0 {
return str[s:]
}
return str[s : s+e]
}
// GetGUID 使用来自 crypto/rand 包的 rand.Read 函数来生成基本的 UUID。
func GetGUID() string {
b := make([]byte, 16)
_, err := rand.Read(b)
if err != nil {
return ""
}
uuid := fmt.Sprintf("%x-%x-%x-%x-%x",
b[0:4], b[4:6], b[6:8], b[8:10], b[10:])
return uuid
}
// GetUUID 使用来自 crypto/rand 包的 rand.Read 函数来生成基本的 UUID。
func GetUUID() string {
b := make([]byte, 16)
_, err := rand.Read(b)
if err != nil {
return ""
}
uuid := fmt.Sprintf("%x%x%x%x%x",
b[0:4], b[4:6], b[6:8], b[8:10], b[10:])
return uuid
}
// CheckMobile 检验手机号
func CheckMobile(phone string) bool {
// 匹配规则
// ^1第一位为一
// [345789]{1} 后接一位345789 的数字
// \\d \d的转义 表示数字 {9} 接9位
// $ 结束符
regRuler := "^1[345789]{1}\\d{9}$"
// 正则调用规则
reg := regexp.MustCompile(regRuler)
// 返回 MatchString 是否匹配
return reg.MatchString(phone)
}
// PhoneCheckRule 手机号验证规则
func PhoneCheckRule() string {
return "^1[3|4|5|6|7|8|9][0-9]\\d{8}$"
}
// EmailCheckRule 邮箱验证规则
func EmailCheckRule() string {
return "^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,6}$"
}
// CheckIdCard 检验身份证
func CheckIdCard(card string) bool {
//18位身份证 ^(\d{17})([0-9]|X)$
// 匹配规则
// (^\d{15}$) 15位身份证
// (^\d{18}$) 18位身份证
// (^\d{17}(\d|X|x)$) 18位身份证 最后一位为X的用户
regRuler := "(^\\d{15}$)|(^\\d{18}$)|(^\\d{17}(\\d|X|x)$)"
// 正则调用规则
reg := regexp.MustCompile(regRuler)
// 返回 MatchString 是否匹配
return reg.MatchString(card)
}
// Buffer 内嵌bytes.Buffer,支持连写
type Buffer struct {
*bytes.Buffer
}
// NewBuffer 创建空字节缓冲
func NewBuffer() *Buffer {
return &Buffer{Buffer: new(bytes.Buffer)}
}
// Append 追加任意类型数据并返回自身(支持链式调用)
func (b *Buffer) Append(i interface{}) *Buffer {
switch val := i.(type) {
case int:
b.append(strconv.Itoa(val))
case int64:
b.append(strconv.FormatInt(val, 10))
case uint:
b.append(strconv.FormatUint(uint64(val), 10))
case uint64:
b.append(strconv.FormatUint(val, 10))
case string:
b.append(val)
case []byte:
b.Write(val)
case rune:
b.WriteRune(val)
}
return b
}
// append 追加字符串(容量不足时自动扩容)
func (b *Buffer) append(s string) *Buffer {
defer func() {
if err := recover(); err != nil {
log.Println("*****内存不够了!******")
}
}()
b.WriteString(s)
return b
}
// Camel2Case 驼峰式写法转为下划线写法
func Camel2Case(name string) string {
buffer := NewBuffer()
for i, r := range name {
if unicode.IsUpper(r) {
if i != 0 {
buffer.Append('_')
}
buffer.Append(unicode.ToLower(r))
} else {
buffer.Append(r)
}
}
return buffer.String()
}