初始化项目

This commit is contained in:
皮蛋13361098506
2025-01-06 16:01:02 +08:00
commit 1b77f62820
575 changed files with 69193 additions and 0 deletions

View File

@@ -0,0 +1,55 @@
package stringUtil
import (
"encoding/base64"
)
const (
base64Table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
// const encodeStd = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
// const encodeURL = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
)
var coder = base64.NewEncoding(base64Table)
// 对字符串进行Base64编码
func Base64Encode(src string) string {
if src == "" {
return src
}
return base64.StdEncoding.EncodeToString([]byte(src))
}
// 对字符串进行Base64解码
func Base64Encode2(src []byte) []byte {
if len(src) == 0 {
return src
}
return []byte(base64.StdEncoding.EncodeToString(src))
}
// 对字符数组进行Base64编码
func Base64Decode(src string) (string, error) {
if src == "" {
return src, nil
}
bytes, err := coder.DecodeString(src)
if err != nil {
return "", err
}
return string(bytes), nil
}
// 对字符数组进行Base64解码
func Base64Decode2(src []byte) ([]byte, error) {
if len(src) == 0 {
return src, nil
}
return coder.DecodeString(string(src))
}

View File

@@ -0,0 +1,53 @@
package stringUtil
import (
"testing"
)
func TestBase64Encode(t *testing.T) {
greeting := "Hello world"
encoded := Base64Encode(greeting)
decoded, err := Base64Decode(encoded)
if err != nil {
t.Errorf("There should be no error, but now there is one:%s", err)
return
}
if greeting != decoded {
t.Errorf("Expected %s, but got %s", greeting, decoded)
return
}
}
func TestBase64Encode2(t *testing.T) {
greeting := []byte("Hello world")
encoded := Base64Encode2(greeting)
decoded, err := Base64Decode2(encoded)
if err != nil {
t.Errorf("There should be no error, but now there is one:%s", err)
return
}
if isEqual(greeting, decoded) == false {
t.Errorf("Expected %s, but got %s", greeting, decoded)
return
}
}
func isEqual(s1, s2 []byte) bool {
if s1 == nil || s2 == nil {
return true
}
if len(s1) != len(s2) {
return false
}
for i := 0; i < len(s1); i++ {
if s1[i] != s2[i] {
return false
}
}
return true
}

View File

@@ -0,0 +1,4 @@
/*
字符串助手类包
*/
package stringUtil

View File

@@ -0,0 +1,198 @@
package stringUtil
// 表情符号集合
var emojiData map[rune]rune
func init() {
emojiData = make(map[rune]rune, 1024)
addEmojiChar()
}
// 添加一个范围的unicode
// start:unicode起始位置
// endlist:unicode结束位置
func addUnicodeRange(start rune, endlist ...rune) {
if len(endlist) <= 0 {
// 添加单个的
emojiData[start] = start
return
}
end := endlist[0]
if start > end {
return
}
// 添加范围的
for i := start; i <= end; i++ {
emojiData[i] = i
}
}
// 增加emoji表情符号
// 表情字符大全参考:
// https://zh.wikipedia.org/wiki/%E7%B9%AA%E6%96%87%E5%AD%97
// 对应unicode版本号Unicode 10.0版本
func addEmojiChar() {
addUnicodeRange(0x00A9)
addUnicodeRange(0x00AE)
addUnicodeRange(0x203C)
addUnicodeRange(0x2049)
addUnicodeRange(0x2122)
addUnicodeRange(0x2139)
addUnicodeRange(0x2194, 0x2199)
addUnicodeRange(0x21A9, 0x21AA)
addUnicodeRange(0x231A, 0x231B)
addUnicodeRange(0x2328)
addUnicodeRange(0x23CF)
addUnicodeRange(0x23E9, 0x23F3)
addUnicodeRange(0x23F8, 0x23FA)
addUnicodeRange(0x24C2)
addUnicodeRange(0x25AA, 0x25AB)
addUnicodeRange(0x25B6)
addUnicodeRange(0x25C0)
addUnicodeRange(0x25FB, 0x25FE)
addUnicodeRange(0x2600, 0x2604)
addUnicodeRange(0x260E)
addUnicodeRange(0x2611)
addUnicodeRange(0x2614, 0x2615)
addUnicodeRange(0x2618)
addUnicodeRange(0x261D)
addUnicodeRange(0x2620)
addUnicodeRange(0x2622, 0x2623)
addUnicodeRange(0x2626)
addUnicodeRange(0x262A)
addUnicodeRange(0x262E, 0x262F)
addUnicodeRange(0x2638, 0x263A)
addUnicodeRange(0x2640)
addUnicodeRange(0x2642)
addUnicodeRange(0x2648, 0x2653)
addUnicodeRange(0x2660)
addUnicodeRange(0x2663)
addUnicodeRange(0x2665, 0x2666)
addUnicodeRange(0x2668)
addUnicodeRange(0x267B)
addUnicodeRange(0x267F)
addUnicodeRange(0x2692, 0x2697)
addUnicodeRange(0x2699)
addUnicodeRange(0x269B, 0x269C)
addUnicodeRange(0x26A0, 0x26A1)
addUnicodeRange(0x26AA, 0x26AB)
addUnicodeRange(0x26B0, 0x26B1)
addUnicodeRange(0x26BD, 0x26BE)
addUnicodeRange(0x26C4, 0x26C5)
addUnicodeRange(0x26C8)
addUnicodeRange(0x26CE, 0x26CF)
addUnicodeRange(0x26D1)
addUnicodeRange(0x26D3, 0x26D4)
addUnicodeRange(0x26E9, 0x26EA)
addUnicodeRange(0x26F0, 0x26F5)
addUnicodeRange(0x26F7, 0x26FA)
addUnicodeRange(0x26FD)
addUnicodeRange(0x2702)
addUnicodeRange(0x2705)
addUnicodeRange(0x2708, 0x270D)
addUnicodeRange(0x270F)
addUnicodeRange(0x2712)
addUnicodeRange(0x2714)
addUnicodeRange(0x2716)
addUnicodeRange(0x271D)
addUnicodeRange(0x2721)
addUnicodeRange(0x2728)
addUnicodeRange(0x2733, 0x2734)
addUnicodeRange(0x2744)
addUnicodeRange(0x2747)
addUnicodeRange(0x274C)
addUnicodeRange(0x274E)
addUnicodeRange(0x2753, 0x2755)
addUnicodeRange(0x2757)
addUnicodeRange(0x2763, 0x2764)
addUnicodeRange(0x2795, 0x2797)
addUnicodeRange(0x27A1)
addUnicodeRange(0x27B0)
addUnicodeRange(0x27BF)
addUnicodeRange(0x2934, 0x2935)
addUnicodeRange(0x2B05, 0x2B07)
addUnicodeRange(0x2B1B, 0x2B1C)
addUnicodeRange(0x2B50)
addUnicodeRange(0x2B55)
addUnicodeRange(0x3030)
addUnicodeRange(0x303D)
addUnicodeRange(0x3297, 0x3299)
addUnicodeRange(0x3299)
addUnicodeRange(0x1F004)
addUnicodeRange(0x1F0CF)
addUnicodeRange(0x1F170, 0x1F171)
addUnicodeRange(0x1F17E, 0x1F17F)
addUnicodeRange(0x1F18E)
addUnicodeRange(0x1F191, 0x1F19A)
addUnicodeRange(0x1F201, 0x1F202)
addUnicodeRange(0x1F21A)
addUnicodeRange(0x1F22F)
addUnicodeRange(0x1F232, 0x1F23A)
addUnicodeRange(0x1F250, 0x1F251)
addUnicodeRange(0x1F300, 0x1F321)
addUnicodeRange(0x1F324, 0x1F393)
addUnicodeRange(0x1F396, 0x1F397)
addUnicodeRange(0x1F399, 0x1F39B)
addUnicodeRange(0x1F39E, 0x1F3F0)
addUnicodeRange(0x1F3F3, 0x1F3F5)
addUnicodeRange(0x1F3F7, 0x1F53D)
addUnicodeRange(0x1F549, 0x1F54E)
addUnicodeRange(0x1F550, 0x1F567)
addUnicodeRange(0x1F56F, 0x1F570)
addUnicodeRange(0x1F573, 0x1F57A)
addUnicodeRange(0x1F587)
addUnicodeRange(0x1F58A, 0x1F58D)
addUnicodeRange(0x1F590)
addUnicodeRange(0x1F595, 0x1F596)
addUnicodeRange(0x1F5A4, 0x1F5A5)
addUnicodeRange(0x1F5A8)
addUnicodeRange(0x1F5B1, 0x1F5B2)
addUnicodeRange(0x1F5BC)
addUnicodeRange(0x1F5C2, 0x1F5C4)
addUnicodeRange(0x1F5D1, 0x1F5D3)
addUnicodeRange(0x1F5DC, 0x1F5DE)
addUnicodeRange(0x1F5E1)
addUnicodeRange(0x1F5E3)
addUnicodeRange(0x1F5E8)
addUnicodeRange(0x1F5EF)
addUnicodeRange(0x1F5F3)
addUnicodeRange(0x1F5FA, 0x1F6C5)
addUnicodeRange(0x1F6CB, 0x1F6D2)
addUnicodeRange(0x1F6E0, 0x1F6E5)
addUnicodeRange(0x1F6E8)
addUnicodeRange(0x1F6EB, 0x1F6EC)
addUnicodeRange(0x1F6F0)
addUnicodeRange(0x1F6F3, 0x1F6F8)
addUnicodeRange(0x1F910, 0x1F93A)
addUnicodeRange(0x1F93B, 0x1F93E)
addUnicodeRange(0x1F940, 0x1F945)
addUnicodeRange(0x1F947, 0x1F94C)
addUnicodeRange(0x1F950, 0x1F96B)
addUnicodeRange(0x1F980, 0x1F997)
addUnicodeRange(0x1F9C0)
addUnicodeRange(0x1F9D0, 0x1F9E6)
}
// 检查是否含有表情字符
// val:待查看的字符串
// 返回值:
// 是否包含有表情字符
func IfHaveEmoji(val string) bool {
// 由于golang在内存中本来就是使用的Unicode所以可以直接进行匹配操作
for _, charItem := range val {
if _, eixst := emojiData[charItem]; eixst {
return true
}
}
return false
}

View File

@@ -0,0 +1,34 @@
package stringUtil
import (
"testing"
)
// test 特殊字符
func TestEmoji1(t *testing.T) {
tstVal := map[string]string{
"中文": "你好啊",
"繁体中文": "這是什麼天氣",
"泰文": "สวัสดีครับ !",
"英文": "helloworld",
"越南语": "Đó là gì thời tiết.",
"日语": "これは何の天気ですか",
"标点符号": "!@#$%^^&*())(__+{}[]|:<>",
}
for key, val := range tstVal {
if IfHaveEmoji(val) {
t.Errorf("语言处理错误:%s", key)
}
}
emojiVal := "☀"
if IfHaveEmoji(emojiVal) == false {
t.Errorf("表情符号匹配错误:")
}
specialChar := "\\'\""
if IfHaveEmoji(specialChar) {
t.Errorf("特殊字符匹配错误:")
}
}

View File

@@ -0,0 +1,60 @@
package stringUtil
import (
"crypto/rand"
"encoding/base64"
"io"
"strings"
"goutil/securityUtil"
)
// 获取新的GUID字符串
// 返回值:
// 新的GUID字符串
func GetNewGUID() string {
b := make([]byte, 48)
if _, err := io.ReadFull(rand.Reader, b); err != nil {
return ""
}
return securityUtil.Md5String(base64.URLEncoding.EncodeToString(b), true)
}
// 生成空的GUID字符串
// 返回值:
// 空的GUID字符串
func GetEmptyGUID() string {
return "00000000-0000-0000-0000-000000000000"
}
// 判断GUID是否为空
// guidGUID
// 返回值:
// 是否为空
func IsGUIDEmpty(guid string) bool {
if guid == "" || guid == "00000000-0000-0000-0000-000000000000" {
return true
}
return false
}
// 获取新的GUID字符串
// 返回值:
// 新的GUID字符串
func GetNewUUID() string {
str := GetNewGUID()
var builder strings.Builder
builder.WriteString(Substring(str, 0, 8))
builder.WriteString("-")
builder.WriteString(Substring(str, 8, 4))
builder.WriteString("-")
builder.WriteString(Substring(str, 12, 4))
builder.WriteString("-")
builder.WriteString(Substring(str, 16, 4))
builder.WriteString("-")
builder.WriteString(Substring(str, 20, 12))
return strings.ToLower(builder.String())
}

View File

@@ -0,0 +1,60 @@
package stringUtil
import (
"testing"
)
func TestGetNewGUID(t *testing.T) {
guidMap := make(map[string]bool, 1024)
count := 10
for i := 0; i < count; i++ {
guid := GetNewGUID()
guidMap[guid] = true
}
if len(guidMap) != count {
t.Errorf("there should be %d 条不重复的数据,但是现在只有%d条", count, len(guidMap))
}
}
func TestGetEmptyGUID(t *testing.T) {
guid := GetEmptyGUID()
expected := "00000000-0000-0000-0000-000000000000"
if guid != expected {
t.Errorf("guid should be %s, but now is %s", expected, guid)
}
}
// test IsGUIDEmpty
func TestIsGUIDEmpty(t *testing.T) {
isOk := IsGUIDEmpty("")
if isOk == false {
t.Error("test is Not pass:")
return
}
isOk = IsGUIDEmpty("00000000-0000-0000-0000-000000000000")
if isOk == false {
t.Error("test is Not pass:00000000-0000-0000-0000-000000000000")
return
}
isOk = IsGUIDEmpty("00000000-0000-0000-0000-000000000001")
if isOk == true {
t.Error("test is Not pass:00000000-0000-0000-0000-000000000001")
return
}
}
func TestGetNewUUID(t *testing.T) {
guidMap := make(map[string]bool, 1024)
count := 10
for i := 0; i < count; i++ {
guid := GetNewUUID()
guidMap[guid] = true
}
if len(guidMap) != count {
t.Errorf("there should be %d 条不重复的数据,但是现在只有%d条", count, len(guidMap))
}
}

View File

@@ -0,0 +1,16 @@
package stringUtil
import (
"hash/crc32"
)
// HashCode 获取字符串对应的hashCode值
func HashCode(s string) int {
v := int(crc32.ChecksumIEEE([]byte(s)))
if v < 0 {
return -v
}
return v
}

View File

@@ -0,0 +1,23 @@
package stringUtil
import (
"testing"
)
func Test1(t *testing.T) {
s := HashCode("abc")
s1 := HashCode("abc")
if s != s1 {
t.Errorf("s1 hashcode:%v,s2 hashcode:%v,2个code值不相等", s, s1)
}
}
func Test2(t *testing.T) {
s := HashCode("abc")
s1 := HashCode("bcd")
if s == s1 {
t.Errorf("s1 hashcode:%v,s2 hashcode:%v,2个code值相等", s, s1)
}
}

View File

@@ -0,0 +1,86 @@
/*
使用编辑距离Edit Distance的方式来计算两个字符串的相似类。
参考资料https://en.wikipedia.org/wiki/Edit_distance
*/
package stringUtil
// 计算两个字符串的相似度
// word1: 第一个字符串
// word2: 第二个字符串
// 返回值:
// 两个字符串的距离,表示两个字符串经过多少次变换,可以变成同一个字符串
// 两个字符串的相似度,范围为[0, 1]
func Similarity(word1, word2 string) (distance int, similarity float64) {
// 内部方法,用于计算最小值、最大值
min := func(nums ...int) int {
_min := nums[0]
for _, v := range nums {
if v < _min {
_min = v
}
}
return _min
}
max := func(nums ...int) int {
_max := nums[0]
for _, v := range nums {
if v > _max {
_max = v
}
}
return _max
}
// 如果有单词为空,或者单词相同,则直接计算出结果,无需进一步计算
m, n := len(word1), len(word2)
if m == 0 {
distance = n
return
}
if n == 0 {
distance = m
return
}
if m == n && word1 == word2 {
distance = 0
similarity = 1
return
}
// 使用动态规划计算编辑距离(Edit Distance)
// Step 1: define the data structure
dp := make([][]int, m+1, m+1)
for i := 0; i <= m; i++ {
dp[i] = make([]int, n+1, n+1)
}
// Step 2: init the data
for i := 0; i <= m; i++ {
for j := 0; j <= n; j++ {
if i == 0 {
dp[i][j] = j
}
if j == 0 {
dp[i][j] = i
}
}
}
// Step 3: state transition equation
for i := 1; i <= m; i++ {
for j := 1; j <= n; j++ {
if word1[i-1] == word2[j-1] {
dp[i][j] = dp[i-1][j-1]
} else {
dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1
}
}
}
// 得到距离并计算相似度
distance = dp[m][n]
maxLength := max(m, n)
similarity = float64(maxLength-distance) / float64(maxLength)
return
}

View File

@@ -0,0 +1,91 @@
package stringUtil
import (
"testing"
)
func TestSimilarity(t *testing.T) {
source := ""
target := ""
expectedDistance := 0
expectedSimilarity := 0.0
gotDistance, gotSimilarity := Similarity(source, target)
if gotDistance != expectedDistance {
t.Errorf("Expected to get %d, now got %d", expectedDistance, gotDistance)
return
}
if gotSimilarity != expectedSimilarity {
t.Errorf("Expected to get %f, now got %f", expectedSimilarity, gotSimilarity)
return
}
source = "Hello"
target = ""
expectedDistance = 5
expectedSimilarity = 0.0
gotDistance, gotSimilarity = Similarity(source, target)
if gotDistance != expectedDistance {
t.Errorf("Expected to get %d, now got %d", expectedDistance, gotDistance)
return
}
if gotSimilarity != expectedSimilarity {
t.Errorf("Expected to get %f, now got %f", expectedSimilarity, gotSimilarity)
return
}
source = ""
target = "Hello"
expectedDistance = 5
expectedSimilarity = 0.0
gotDistance, gotSimilarity = Similarity(source, target)
if gotDistance != expectedDistance {
t.Errorf("Expected to get %d, now got %d", expectedDistance, gotDistance)
return
}
if gotSimilarity != expectedSimilarity {
t.Errorf("Expected to get %f, now got %f", expectedSimilarity, gotSimilarity)
return
}
source = "Helo"
target = "Hello"
expectedDistance = 1
expectedSimilarity = 4.0 / 5.0
gotDistance, gotSimilarity = Similarity(source, target)
if gotDistance != expectedDistance {
t.Errorf("Expected to get %d, now got %d", expectedDistance, gotDistance)
return
}
if gotSimilarity != expectedSimilarity {
t.Errorf("Expected to get %f, now got %f", expectedSimilarity, gotSimilarity)
return
}
source = "kitten"
target = "sitten"
expectedDistance = 1
expectedSimilarity = 5.0 / 6.0
gotDistance, gotSimilarity = Similarity(source, target)
if gotDistance != expectedDistance {
t.Errorf("Expected to get %d, now got %d", expectedDistance, gotDistance)
return
}
if gotSimilarity != expectedSimilarity {
t.Errorf("Expected to get %f, now got %f", expectedSimilarity, gotSimilarity)
return
}
source = "Michael Jordan"
target = "Michael Jordan"
expectedDistance = 0
expectedSimilarity = 1
gotDistance, gotSimilarity = Similarity(source, target)
if gotDistance != expectedDistance {
t.Errorf("Expected to get %d, now got %d", expectedDistance, gotDistance)
return
}
if gotSimilarity != expectedSimilarity {
t.Errorf("Expected to get %f, now got %f", expectedSimilarity, gotSimilarity)
return
}
}

View File

@@ -0,0 +1,330 @@
package stringUtil
import (
"fmt"
"strconv"
"strings"
"goutil/mathUtil"
)
// 使用多分隔符来进行分割(默认分隔符为:",", ";", ":", "|", "||")
// eg:1,2;3|4||5,6;7|8||9
// 返回值:
// []string
func Split(s string, seps []string) []string {
retList := make([]string, 0, 32)
// 如果seps为nil则使用默认值
if seps == nil {
seps = []string{",", ";", ":", "|", "||"}
}
// 根据所有的分隔符来一点一点地切割字符串,直到不可切割为止
for {
startIndex := len(s) - 1
endIndex := 0
exists := false
// 遍历,找到第一个分割的位置
for _, sep := range seps {
index := strings.Index(s, sep)
// 如果找到有匹配项则寻找最小的pos如果有多个相同的pos则使用长度最长的分隔符
if index > -1 {
exists = true
// 说明有多个有效的分隔符,如|和||
if index < startIndex {
startIndex = index
endIndex = startIndex + len(sep) - 1
} else if index == startIndex {
if startIndex+len(sep)-1 > endIndex {
endIndex = startIndex + len(sep) - 1
}
}
}
}
// 如果没有找到匹配的pos则分割过程结束
if !exists {
retList = append(retList, s)
break
}
// 切割字符串
sub := s[:startIndex]
if sub != "" {
retList = append(retList, sub)
}
s = s[endIndex+1:]
}
return retList
}
// 将字符串切割为[]int
// str:输入字符串
// 返回值:
// []int
// error
func SplitToIntSlice(s, sep string) ([]int, error) {
// 先按照分隔符进行切割
strSlice := strings.Split(s, sep)
// 定义int slice
intSlice := make([]int, 0, len(strSlice))
for _, value := range strSlice {
// 去除空格
if value = strings.TrimSpace(value); value == "" {
continue
}
if value_int, err := strconv.Atoi(value); err != nil {
return nil, err
} else {
intSlice = append(intSlice, value_int)
}
}
return intSlice, nil
}
// 将字符串切割为[]int32
// s:输入字符串
// 返回值:
// []int
// error
func SplitToInt32Slice(s, sep string) ([]int32, error) {
// 先获得int slice
count := 0
intSlice, err := SplitToIntSlice(s, sep)
if err != nil {
return nil, err
} else {
count = len(intSlice)
}
// 定义int32 slice
int32Slice := make([]int32, 0, count)
for _, item := range intSlice {
int32Slice = append(int32Slice, int32(item))
}
return int32Slice, nil
}
// 将字符串切割为[]int64
// s:输入字符串
// 返回值:
// []int64
// error
func SplitToInt64Slice(s, sep string) ([]int64, error) {
// 先获得int slice
count := 0
intSlice, err := SplitToIntSlice(s, sep)
if err != nil {
return nil, err
} else {
count = len(intSlice)
}
// 定义int32 slice
int64Slice := make([]int64, 0, count)
for _, item := range intSlice {
int64Slice = append(int64Slice, int64(item))
}
return int64Slice, nil
}
// 将字符串切割为[]float64
// s:输入字符串
// 返回值:
// []float64
// error
func SplitToFloat64Slice(s, sep string) ([]float64, error) {
// 先按照分隔符进行切割
strSlice := strings.Split(s, sep)
// 定义float64 slice
floatSlice := make([]float64, 0, len(strSlice))
for _, value := range strSlice {
// 去除空格
if value = strings.TrimSpace(value); value == "" {
continue
}
if value_float, err := strconv.ParseFloat(value, 64); err != nil {
return nil, err
} else {
floatSlice = append(floatSlice, value_float)
}
}
return floatSlice, nil
}
// 将字符串切割为map[int32]int32
// s:输入字符串
// 返回值:
// map[int32]float32
// error
func SplitToDict_KintVint(s, outerSep, innerSep string) (map[int32]int32, error) {
// 先按照分隔符进行切割
outerSlice := strings.Split(s, outerSep)
// 定义map[int32]float32
floatMap := make(map[int32]int32, len(outerSlice))
for _, itemStr := range outerSlice {
innerSlice := strings.Split(strings.TrimSpace(itemStr), innerSep)
key := strings.TrimSpace(innerSlice[0])
value := strings.TrimSpace(innerSlice[1])
key_int, err := strconv.Atoi(key)
if err != nil {
return nil, err
}
value_int, err := strconv.Atoi(value)
if err != nil {
return nil, err
}
floatMap[int32(key_int)] = int32(value_int)
}
return floatMap, nil
}
// 将字符串切割为map[int32]string
// s:输入字符串
// 返回值:
// map[int32]string
// error
func SplitToDict_KintVstring(s, outerSep, innerSep string) (map[int32]string, error) {
// 先按照分隔符进行切割
outerSlice := strings.Split(s, outerSep)
// 定义map[int32]string
resultMap := make(map[int32]string, len(outerSlice))
for _, itemStr := range outerSlice {
innerSlice := strings.Split(strings.TrimSpace(itemStr), innerSep)
key := strings.TrimSpace(innerSlice[0])
value := strings.TrimSpace(innerSlice[1])
key_int, err := strconv.Atoi(key)
if err != nil {
return nil, err
}
resultMap[int32(key_int)] = value
}
return resultMap, nil
}
// 将字符串切割为map[int32]float32
// s:输入字符串
// 返回值:
// map[int32]float32
// error
func SplitToDict_KintVfloat(s, outerSep, innerSep string) (map[int32]float32, error) {
// 先按照分隔符进行切割
outerSlice := strings.Split(s, outerSep)
// 定义map[int32]float32
floatMap := make(map[int32]float32, len(outerSlice))
for _, itemStr := range outerSlice {
innerSlice := strings.Split(strings.TrimSpace(itemStr), innerSep)
key := strings.TrimSpace(innerSlice[0])
value := strings.TrimSpace(innerSlice[1])
key_int, err := strconv.Atoi(key)
if err != nil {
return nil, err
}
value_float, err := strconv.ParseFloat(value, 64)
if err != nil {
return nil, err
}
floatMap[int32(key_int)] = float32(value_float)
}
return floatMap, nil
}
// 将字符串切割为map[int32]float32
// s:输入字符串
// 返回值:
// map[int32]float32
// error
func SplitToDict_KintVfloat64(s, outerSep, innerSep string) (map[int32]float64, error) {
// 先按照分隔符进行切割
outerSlice := strings.Split(s, outerSep)
// 定义map[int32]float32
floatMap := make(map[int32]float64, len(outerSlice))
for _, itemStr := range outerSlice {
innerSlice := strings.Split(strings.TrimSpace(itemStr), innerSep)
key := strings.TrimSpace(innerSlice[0])
value := strings.TrimSpace(innerSlice[1])
key_int, err := strconv.Atoi(key)
if err != nil {
return nil, err
}
value_float, err := strconv.ParseFloat(value, 64)
if err != nil {
return nil, err
}
floatMap[int32(key_int)] = float64(value_float)
}
return floatMap, nil
}
// 将字符串切割为IntRegion列表
// s:输入字符串形如1-200,201-400,401-1000
// outerSep:外部分隔符
// innerSep:内部分隔符
// 返回值:
// IntRegion列表
// 错误对象
func SplitToIntRegion(s, outerSep, innerSep string) (intRegionList []*mathUtil.IntRegion, err error) {
if s == "" {
err = fmt.Errorf("Input is empty")
return
}
outerRegionList := make([]string, 0, 4)
outerRegionList = strings.Split(s, outerSep)
if len(outerRegionList) == 0 {
err = fmt.Errorf("%s:Format invalid. Such as:1-100,101-200", s)
return
}
for _, item := range outerRegionList {
innerRegionList := make([]string, 0, 2)
innerRegionList = strings.Split(item, innerSep)
if len(innerRegionList) != 2 {
err = fmt.Errorf("%s:Format invalid. Such as:1-100", item)
return
}
var lower, upper int
lower, err = strconv.Atoi(innerRegionList[0])
if err != nil {
return
}
upper, err = strconv.Atoi(innerRegionList[1])
if err != nil {
return
}
if lower > upper {
err = fmt.Errorf("lower:%d should less than upper:%d", lower, upper)
return
}
intRegionList = append(intRegionList, mathUtil.NewIntRegion(lower, upper))
}
return
}

View File

@@ -0,0 +1,78 @@
package stringUtil
import (
"fmt"
"testing"
)
func TestSplit(t *testing.T) {
s := "1,2;3|4||5,6;7|8||9,"
// seps := []string{",", ";", "|", "||"}
retList := Split(s, nil)
if retList[0] != "1" || retList[1] != "2" || retList[2] != "3" || retList[3] != "4" || retList[4] != "5" || retList[5] != "6" || retList[6] != "7" || retList[7] != "8" || retList[8] != "9" {
t.Errorf("ecptected:123456789, but now got:%v", retList)
}
}
func TestSplitToIntSlice(t *testing.T) {
s := "1, 2, 3, 4, 5, a"
if _, err := SplitToIntSlice(s, ","); err == nil {
t.Errorf("Expected got err, but got nil")
}
s = "1, 5, 39,"
if intSlice, err := SplitToIntSlice(s, ","); err != nil {
t.Errorf("Expected got nil, but got error:%s", err)
} else {
// fmt.Printf("intSlice:%v\n", intSlice)
if intSlice[0] != 1 || intSlice[1] != 5 || intSlice[2] != 39 {
t.Errorf("Expected got %s, but got %v", s, intSlice)
}
}
}
func TestSplitToIntRegion(t *testing.T) {
idRegionStr := ""
outerSep := ","
innerSep := "-"
var err error
if _, err = SplitToIntRegion(idRegionStr, outerSep, innerSep); err == nil {
t.Errorf("PraseIdRegion should failed, but now not.err:%s", err)
}
idRegionStr = ","
if _, err = SplitToIntRegion(idRegionStr, outerSep, innerSep); err == nil {
t.Errorf("PraseIdRegion should failed, but now not.err:%s", err)
}
idRegionStr = "1-100,101,200"
if _, err = SplitToIntRegion(idRegionStr, outerSep, innerSep); err == nil {
t.Errorf("PraseIdRegion should failed, but now not.err:%s", err)
}
idRegionStr = "1-100,101-20"
if _, err = SplitToIntRegion(idRegionStr, outerSep, innerSep); err == nil {
t.Errorf("PraseIdRegion should failed, but now not.err:%s", err)
}
idRegionStr = "1-100,101-200"
if idRegionList, err := SplitToIntRegion(idRegionStr, outerSep, innerSep); err != nil {
t.Errorf("PraseIdRegion should succeed, but now failed.err:%s", err)
} else {
if idRegionList[0].Lower != 1 || idRegionList[0].Upper != 100 ||
idRegionList[1].Lower != 101 || idRegionList[1].Upper != 200 {
t.Errorf("SplitToIntRegion should succeed, but now failed. idRegionStr:%s, idRegionList:%v", idRegionStr, idRegionList)
}
}
}
func TestSplitToFloat64(t *testing.T) {
result, err := SplitToFloat64Slice("1.11,2.22", ",")
if err != nil {
t.Error(err)
return
}
fmt.Printf("%v\n", result)
}

View File

@@ -0,0 +1,142 @@
package stringUtil
import (
"regexp"
"runtime"
"sort"
"strconv"
"strings"
"unicode"
)
// 检查一个字符串是否是空字符串
// content:上下文字符串
// 返回值:
// bool:true空字符串 false非空字符串
func IsEmpty(content string) bool {
if len(content) <= 0 {
return true
}
return strings.IndexFunc(content, func(item rune) bool {
return unicode.IsSpace(item) == false
}) < 0
}
// 截取字符串
// start开始位置
// length截取长度
// 返回值:
// 截取后的字符串
func Substring(str string, start, length int) string {
// 先将字符串转化为[]rune格式由于rune是字符串的基本单位
runeString := []rune(str)
runeLength := len(runeString)
end := 0
// 计算起始位置
if start > runeLength {
start = runeLength
}
// 计算终止位置
end = start + length
if end > runeLength {
end = runeLength
}
if start > end {
start, end = end, start
}
return string(runeString[start:end])
}
// 根据不同平台获取换行符
// 返回值:
// 换行符
func GetNewLineString() string {
switch os := runtime.GOOS; os {
case "windows":
return "\r\n"
default:
return "\n"
}
}
// 检查是否存在特殊符号
// 1. emoji字符
// 2. ascii控制字符
// 3. \ " '
// val:待检查的字符串
// 返回值:
// bool:true:有特殊字符 false:无特殊字符
func IfHaveSpecialChar(val string) bool {
if len(val) <= 0 {
return false
}
// 表情符号过滤
// Wide UCS-4 build
emojiReg, _ := regexp.Compile("[^\U00000000-\U0000FFFF]+")
if emojiReg.Match([]byte(val)) {
return true
}
// 排除控制字符和特殊字符
for _, charItem := range val {
// 排除控制字符
if (charItem > 0 && charItem < 0x20) || charItem == 0x7F {
return true
}
// 排除部分特殊字符: \ " '
switch charItem {
case '\\':
fallthrough
case '"':
fallthrough
case '\'':
return true
}
}
return false
}
// 判断string数组是否内容唯一
func IsDistinct_string(list []string) (result bool) {
if len(list) == 0 || len(list) == 1 {
result = true
return
}
sort.Strings(list)
for i := 0; i < len(list)-1; i++ {
if list[i] == list[i+1] {
result = false
return
}
}
result = true
return
}
// 验证是否是电话号码
func VerifyPhone(phone string) bool {
regular := "^1[3-9]\\d{9}$"
reg := regexp.MustCompile(regular)
return reg.MatchString(phone)
}
// 转型成int64
func StringToInt64(str string) int64 {
num, err := strconv.ParseInt(str, 10, 64)
if err != nil {
return 0
}
return num
}

View File

@@ -0,0 +1,57 @@
package stringUtil
import (
"bytes"
"fmt"
)
type StringBuilder struct {
buffer bytes.Buffer
}
func NewStringBuilder() *StringBuilder {
var builder StringBuilder
return &builder
}
func (builder *StringBuilder) Append(format string, args ...interface{}) *StringBuilder {
if len(args) > 0 {
format = fmt.Sprintf(format, args...)
}
builder.buffer.WriteString(format)
return builder
}
func (builder *StringBuilder) AppendLine(format string, args ...interface{}) *StringBuilder {
if len(args) > 0 {
format = fmt.Sprintf(format, args...)
}
builder.buffer.WriteString(format + "\n")
return builder
}
func (builder *StringBuilder) AppendStrings(ss ...string) *StringBuilder {
for i := range ss {
builder.buffer.WriteString(ss[i])
}
return builder
}
func (builder *StringBuilder) AppendLines(ss ...string) *StringBuilder {
for i := range ss {
builder.buffer.WriteString(ss[i] + "\n")
}
return builder
}
func (builder *StringBuilder) Clear() *StringBuilder {
var buffer bytes.Buffer
builder.buffer = buffer
return builder
}
func (builder *StringBuilder) ToString() string {
return builder.buffer.String()
}

View File

@@ -0,0 +1,120 @@
package stringUtil
import (
"fmt"
"testing"
)
// test IsEmpty
func TestIsEmpty(t *testing.T) {
isOk := IsEmpty("")
if isOk == false {
t.Error("\"\" test is Not pass")
return
}
isOk = IsEmpty(" ")
if isOk == false {
t.Error("\" \" test is Not pass")
return
}
isOk = IsEmpty(" \t\n")
if isOk == false {
t.Error("\" \\t\\n\" test is Not pass")
return
}
}
func TestSubstr(t *testing.T) {
str := "Hello, Jordan.左贤清"
substr := Substring(str, 0, 5)
expectedstr := "Hello"
if substr != expectedstr {
t.Errorf("Failed. Expected:%s, Got %s\n", expectedstr, substr)
}
substr = Substring(str, 0, 10)
expectedstr = "Hello, Jor"
if substr != expectedstr {
t.Errorf("Failed. Expected:%s, Got %s\n", expectedstr, substr)
}
substr = Substring(str, 0, 15)
expectedstr = "Hello, Jordan.左"
if substr != expectedstr {
t.Errorf("Failed. Expected:%s, Got %s\n", expectedstr, substr)
}
substr = Substring(str, 0, 20)
expectedstr = "Hello, Jordan.左贤清"
if substr != expectedstr {
t.Errorf("Failed. Expected:%s, Got %s\n", expectedstr, substr)
}
guid1 := GetNewGUID()
guid2 := GetNewGUID()
fmt.Printf("guid1:%s, guid2:%s\n", guid1, guid2)
fmt.Printf("length of %s is %d\n", guid1, len(guid1))
if guid1 == guid2 {
t.Errorf("%s should not be equal with %s", guid1, guid2)
}
}
// test 特殊字符
func TestIfHaveSpecialChar(t *testing.T) {
tstVal := map[string]string{
"中文": "你好啊",
"繁体中文": "這是什麼天氣",
"泰文": "สวัสดีครับ !",
"英文": "helloworld",
"越南语": "Đó là gì thời tiết.",
"日语": "これは何の天気ですか",
"标点符号": "!@#$%^^&*())(__+{}[]|:<>",
}
for key, val := range tstVal {
if IfHaveSpecialChar(val) {
t.Errorf("语言处理错误:%s", key)
}
}
specialChar := "\\'\""
if IfHaveSpecialChar(specialChar) == false {
t.Errorf("特殊字符匹配错误:")
}
}
func TestIsDistinct_string(t *testing.T) {
list := make([]string, 0, 8)
result := IsDistinct_string(list)
fmt.Printf("list:%v,result:%v-------1\n", list, result)
if result == false {
t.Errorf("it's should be true, but now false-------1")
}
list = append(list, "Hello")
result = IsDistinct_string(list)
fmt.Printf("list:%v,result:%v-------2\n", list, result)
if result == false {
t.Errorf("it's should be true, but now false-------2")
}
list = append(list, "Hello")
result = IsDistinct_string(list)
fmt.Printf("list:%v,result:%v-------3\n", list, result)
if result {
t.Errorf("it's should be false, but now true-------3")
}
list = append(list, "")
result = IsDistinct_string(list)
fmt.Printf("list:%v,result:%v-------4\n", list, result)
if result {
t.Errorf("it's should be false, but now true-------4")
}
}

View File

@@ -0,0 +1,158 @@
package stringUtil
import (
"bytes"
"fmt"
"reflect"
)
// map转换为字符串(如果类型不匹配)
// data:map数据
// separator1:间隔符1
// separator1:间隔符2
// 返回值:
// result:转换后的字符串
// err:错误信息
func MapToString(data interface{}, separator1, separator2 string) (result string, err error) {
if data == nil {
return
}
val := reflect.ValueOf(data)
if val.Kind() != reflect.Map {
err = fmt.Errorf("只能转换Map类型的当前类型是:%v", val.Kind().String())
return
}
if val.Len() <= 0 {
return
}
for _, keyItem := range val.MapKeys() {
valItem := val.MapIndex(keyItem)
result = result + fmt.Sprintf("%v%s%v%s", keyItem.Interface(), separator1, valItem.Interface(), separator2)
}
result = result[:len(result)-1]
return
}
// map转换为字符串(如果类型不匹配)
// data:map数据
// separator1:间隔符1
// separator1:间隔符2
// valGetFunc:结果值获取函数
// 返回值:
// result:转换后的字符串
// err:错误信息
func MapToString2(data interface{}, separator1, separator2 string, valGetFunc func(val interface{}) interface{}) (result string, err error) {
if data == nil {
return
}
val := reflect.ValueOf(data)
if val.Kind() != reflect.Map {
err = fmt.Errorf("只能转换Map类型的当前类型是:%v", val.Kind().String())
return
}
if val.Len() <= 0 {
return
}
for _, keyItem := range val.MapKeys() {
valItem := val.MapIndex(keyItem)
result = result + fmt.Sprintf("%v%s%v%s", keyItem.Interface(), separator1, valGetFunc(valItem.Interface()), separator2)
}
result = result[:len(result)-1]
return
}
// 把一个集合转换成字符串
// data:slice类型的集合
// separator:分隔符
// 返回值:
// result:转换后的字符串
// err:错误信息对象
func SliceToString(data interface{}, separator string) (result string, err error) {
if data == nil {
return
}
value := reflect.ValueOf(data)
if value.Kind() != reflect.Slice && value.Kind() != reflect.Array {
err = fmt.Errorf("目标类型不正确只能是slice或array 当前类型是:%v", value.Kind().String())
return
}
if value.Len() <= 0 {
return
}
for i := 0; i < value.Len(); i++ {
valItem := value.Index(i)
result = result + fmt.Sprintf("%s%v", separator, valItem.Interface())
}
result = result[1:]
return
}
func StringListToString(list []string, delimiter string) string {
var buffer bytes.Buffer
for i, v := range list {
if i != len(list)-1 {
buffer.WriteString(v)
buffer.WriteString(delimiter)
} else {
buffer.WriteString(v)
}
}
return buffer.String()
}
func IntListToString(list []int, delimiter string) string {
var buffer bytes.Buffer
for i, v := range list {
if i != len(list)-1 {
buffer.WriteString(fmt.Sprintf("%d", v))
buffer.WriteString(delimiter)
} else {
buffer.WriteString(fmt.Sprintf("%d", v))
}
}
return buffer.String()
}
func Int32ListToString(list []int32, delimiter string) string {
var buffer bytes.Buffer
for i, v := range list {
if i != len(list)-1 {
buffer.WriteString(fmt.Sprintf("%d", v))
buffer.WriteString(delimiter)
} else {
buffer.WriteString(fmt.Sprintf("%d", v))
}
}
return buffer.String()
}
func Int64ListToString(list []int64, delimiter string) string {
var buffer bytes.Buffer
for i, v := range list {
if i != len(list)-1 {
buffer.WriteString(fmt.Sprintf("%d", v))
buffer.WriteString(delimiter)
} else {
buffer.WriteString(fmt.Sprintf("%d", v))
}
}
return buffer.String()
}

View File

@@ -0,0 +1,169 @@
package stringUtil
import (
"testing"
)
func TestMapToString(t *testing.T) {
var data map[string]int
separator1 := ","
separator2 := ";"
got, err := MapToString(data, separator1, separator2)
if err != nil {
t.Errorf("There should be no error, but now there is:%s", err)
return
}
data1 := make([]int, 0, 4)
data1 = append(data1, 1)
got, err = MapToString(data1, separator1, separator2)
if err == nil {
t.Errorf("There should be an error, but now there is not")
return
}
data2 := make(map[string]int, 4)
data2["Jordan"] = 34
data2["Thomas"] = 6
expected1 := "Jordan,34;Thomas,6"
expected2 := "Thomas,6;Jordan,34"
got, err = MapToString(data2, separator1, separator2)
if err != nil {
t.Errorf("There should be no error, but now there is:%s", err)
return
}
if got != expected1 && got != expected2 {
t.Errorf("Expected to get:%s or %s, but got:%s", expected1, expected2, got)
}
}
func TestMapToString2(t *testing.T) {
var data map[string]int
separator1 := ","
separator2 := ";"
got, err := MapToString2(data, separator1, separator2, valGetFunc)
if err != nil {
t.Errorf("There should be no error, but now there is:%s", err)
return
}
data1 := make([]int, 0, 4)
data1 = append(data1, 1)
got, err = MapToString2(data1, separator1, separator2, valGetFunc)
if err == nil {
t.Errorf("There should be an error, but now there is not")
return
}
data2 := make(map[string]int, 4)
data2["Jordan"] = 34
data2["Thomas"] = 6
expected1 := "Jordan,34;Thomas,6"
expected2 := "Thomas,6;Jordan,34"
got, err = MapToString2(data2, separator1, separator2, valGetFunc)
if err != nil {
t.Errorf("There should be no error, but now there is:%s", err)
return
}
if got != expected1 && got != expected2 {
t.Errorf("Expected to get:%s or %s, but got:%s", expected1, expected2, got)
}
}
func valGetFunc(val interface{}) interface{} {
return val
}
func TestSliceToString(t *testing.T) {
// Test with nil value
var value interface{} = nil
expected := ""
got, err := SliceToString(value, ",")
if err != nil {
t.Errorf("There should be no error, but now got one. %s", err)
return
}
// Test with wrong type value
value = "hello"
got, err = SliceToString(value, ",")
if err == nil {
t.Errorf("There should be an error, but now there isn't.")
return
}
// Test with correct value
value = []int{1, 2, 3, 4, 5}
expected = "1,2,3,4,5"
got, err = SliceToString(value, ",")
if err != nil {
t.Errorf("There should be no error, but now got one. %s", err)
return
}
if got != expected {
t.Errorf("Expected %s, but got %s", expected, got)
return
}
}
func TestStringListToString(t *testing.T) {
list := make([]string, 0, 4)
list = append(list, "Hello")
list = append(list, "World")
list = append(list, "Hello")
list = append(list, "Apple")
expected := "Hello,World,Hello,Apple"
got := StringListToString(list, ",")
if expected != got {
t.Errorf("Expected:%s, but got:%s", expected, got)
}
}
func TestIntListToString(t *testing.T) {
list := make([]int, 0, 4)
list = append(list, 1)
list = append(list, 2)
list = append(list, 3)
list = append(list, 4)
expected := "1,2,3,4"
got := IntListToString(list, ",")
if expected != got {
t.Errorf("Expected:%s, but got:%s", expected, got)
}
}
func TestInt64ListToString(t *testing.T) {
list := make([]int64, 0, 4)
list = append(list, 1)
list = append(list, 2)
list = append(list, 3)
list = append(list, 4)
expected := "1,2,3,4"
got := Int64ListToString(list, ",")
if expected != got {
t.Errorf("Expected:%s, but got:%s", expected, got)
}
}
func TestInt32ListToString(t *testing.T) {
list := make([]int32, 0, 4)
list = append(list, 1)
list = append(list, 2)
list = append(list, 3)
list = append(list, 4)
expected := "1,2,3,4"
got := Int32ListToString(list, ",")
if expected != got {
t.Errorf("Expected:%s, but got:%s", expected, got)
}
}

View File

@@ -0,0 +1,190 @@
package stringUtil
import (
"fmt"
"strconv"
)
// 首字母小写
func FirstCharToLower(str string) string {
if len(str) < 1 {
return ""
}
runeArray := []rune(str)
if runeArray[0] >= 65 && runeArray[0] <= 90 {
runeArray[0] += 32
}
return string(runeArray)
}
// 首字母大写
func FirstCharToUpper(str string) string {
if len(str) < 1 {
return ""
}
runeArray := []rune(str)
if runeArray[0] >= 97 && runeArray[0] <= 122 {
runeArray[0] -= 32
}
return string(runeArray)
}
// 将形如1,2|3,4|5,6的字符串转化成map
// 返回值:
// map[string]string
// 错误对象
func StringToMap_String_String(str string, seps []string) (data map[string]string, err error) {
strList := Split(str, seps)
if len(strList) == 0 {
err = fmt.Errorf("str is empty.")
return
}
if len(strList)%2 != 0 {
err = fmt.Errorf("str has odd items.")
return
}
data = make(map[string]string, len(strList)/2)
for i := 0; i < len(strList); i += 2 {
data[strList[i]] = strList[i+1]
}
return
}
// 将形如1,2|3,4|5,6的字符串转化成map
// 返回值:
// map[string]int
// 错误对象
func StringToMap_String_Int(str string, seps []string) (data map[string]int, err error) {
strList := Split(str, seps)
if len(strList) == 0 {
err = fmt.Errorf("str is empty.")
return
}
if len(strList)%2 != 0 {
err = fmt.Errorf("str has odd items.")
return
}
data = make(map[string]int, len(strList)/2)
for i := 0; i < len(strList); i += 2 {
key := strList[i]
value, err1 := strconv.Atoi(strList[i+1])
if err1 != nil {
err = fmt.Errorf("Type convertion failed. Value:%s, Error:%v", strList[i+1], err1)
return
}
data[key] = value
}
return
}
// 将形如1,2|3,4|5,6的字符串转化成map
// 返回值:
// map[int]int
// 错误对象
func StringToMap_Int_Int(str string, seps []string) (data map[int]int, err error) {
strList := Split(str, seps)
if len(strList) == 0 {
err = fmt.Errorf("str is empty.")
return
}
if len(strList)%2 != 0 {
err = fmt.Errorf("str has odd items.")
return
}
data = make(map[int]int, len(strList)/2)
for i := 0; i < len(strList); i += 2 {
key, err1 := strconv.Atoi(strList[i])
if err1 != nil {
err = fmt.Errorf("Type convertion failed. Value:%s, Error:%v", strList[i], err1)
return
}
value, err2 := strconv.Atoi(strList[i+1])
if err2 != nil {
err = fmt.Errorf("Type convertion failed. Value:%s, Error:%v", strList[i+1], err2)
return
}
data[key] = value
}
return
}
// 将形如1,2|3,4|5,6的字符串转化成map
// 返回值:
// map[int32]int32
// 错误对象
func StringToMap_Int32_Int32(str string, seps []string) (data map[int32]int32, err error) {
strList := Split(str, seps)
if len(strList) == 0 {
err = fmt.Errorf("str is empty.")
return
}
if len(strList)%2 != 0 {
err = fmt.Errorf("str has odd items.")
return
}
data = make(map[int32]int32, len(strList)/2)
for i := 0; i < len(strList); i += 2 {
key, err1 := strconv.Atoi(strList[i])
if err1 != nil {
err = fmt.Errorf("Type convertion failed. Value:%s, Error:%v", strList[i], err1)
return
}
value, err2 := strconv.Atoi(strList[i+1])
if err2 != nil {
err = fmt.Errorf("Type convertion failed. Value:%s, Error:%v", strList[i+1], err2)
return
}
data[int32(key)] = int32(value)
}
return
}
// 将形如1,2|3,4|5,6的字符串转化成map
// 返回值:
// map[int32]int64
// 错误对象
func StringToMap_Int32_Int64(str string, seps []string) (data map[int32]int64, err error) {
strList := Split(str, seps)
if len(strList) == 0 {
err = fmt.Errorf("str is empty.")
return
}
if len(strList)%2 != 0 {
err = fmt.Errorf("str has odd items.")
return
}
data = make(map[int32]int64, len(strList)/2)
for i := 0; i < len(strList); i += 2 {
key, err1 := strconv.Atoi(strList[i])
if err1 != nil {
err = fmt.Errorf("Type convertion failed. Value:%s, Error:%v", strList[i], err1)
return
}
value, err2 := strconv.ParseInt(strList[i+1], 10, 64)
if err2 != nil {
err = fmt.Errorf("Type convertion failed. Value:%s, Error:%v", strList[i+1], err2)
return
}
data[int32(key)] = value
}
return
}

View File

@@ -0,0 +1,259 @@
package stringUtil
import (
"testing"
)
func TestStringToMap_String_String(t *testing.T) {
str := ""
seps := []string{",", "|"}
data, err := StringToMap_String_String(str, seps)
if err == nil {
t.Errorf("Expected to get an error. But now there isn't.")
return
}
str = "1,2|3"
data, err = StringToMap_String_String(str, seps)
if err == nil {
t.Errorf("Expected to get an error. But now there isn't.")
return
}
str = "1,2|3,5"
data, err = StringToMap_String_String(str, seps)
if err != nil {
t.Errorf("Expected to get no error. But now there is one:%v.", err)
return
}
expected := make(map[string]string, 2)
expected["1"] = "2"
expected["3"] = "5"
if len(expected) != len(data) {
t.Errorf("The length of expected:%d is not equals to length of data:%d", len(expected), len(data))
return
}
for k, v := range data {
if v1, exists := expected[k]; !exists {
t.Errorf("data is not equals to expected. %v, %v", expected, data)
} else if v != v1 {
t.Errorf("data is not equals to expected. %v, %v", expected, data)
}
}
}
func TestStringToMap_String_Int(t *testing.T) {
str := ""
seps := []string{",", "|"}
data, err := StringToMap_String_Int(str, seps)
if err == nil {
t.Errorf("Expected to get an error. But now there isn't.")
return
}
str = "1,2|3"
data, err = StringToMap_String_Int(str, seps)
if err == nil {
t.Errorf("Expected to get an error. But now there isn't.")
return
}
str = "1,2|3,abc"
data, err = StringToMap_String_Int(str, seps)
if err == nil {
t.Errorf("Expected to get an error. But now there isn't.")
return
}
str = "1,2|3,5"
data, err = StringToMap_String_Int(str, seps)
if err != nil {
t.Errorf("Expected to get no error. But now there is one:%v.", err)
return
}
expected := make(map[string]int, 2)
expected["1"] = 2
expected["3"] = 5
if len(expected) != len(data) {
t.Errorf("The length of expected:%d is not equals to length of data:%d", len(expected), len(data))
return
}
for k, v := range data {
if v1, exists := expected[k]; !exists {
t.Errorf("data is not equals to expected. %v, %v", expected, data)
} else if v != v1 {
t.Errorf("data is not equals to expected. %v, %v", expected, data)
}
}
}
func TestStringToMap_Int_Int(t *testing.T) {
str := ""
seps := []string{",", "|"}
data, err := StringToMap_Int_Int(str, seps)
if err == nil {
t.Errorf("Expected to get an error. But now there isn't.")
return
}
str = "1,2|3"
data, err = StringToMap_Int_Int(str, seps)
if err == nil {
t.Errorf("Expected to get an error. But now there isn't.")
return
}
str = "1,2|3,abc"
data, err = StringToMap_Int_Int(str, seps)
if err == nil {
t.Errorf("Expected to get an error. But now there isn't.")
return
}
str = "1,2|a,3"
data, err = StringToMap_Int_Int(str, seps)
if err == nil {
t.Errorf("Expected to get an error. But now there isn't.")
return
}
str = "1,2|3,5"
data, err = StringToMap_Int_Int(str, seps)
if err != nil {
t.Errorf("Expected to get no error. But now there is one:%v.", err)
return
}
expected := make(map[int]int, 2)
expected[1] = 2
expected[3] = 5
if len(expected) != len(data) {
t.Errorf("The length of expected:%d is not equals to length of data:%d", len(expected), len(data))
return
}
for k, v := range data {
if v1, exists := expected[k]; !exists {
t.Errorf("data is not equals to expected. %v, %v", expected, data)
} else if v != v1 {
t.Errorf("data is not equals to expected. %v, %v", expected, data)
}
}
}
func TestStringToMap_Int32_Int32(t *testing.T) {
str := ""
seps := []string{",", "|"}
data, err := StringToMap_Int32_Int32(str, seps)
if err == nil {
t.Errorf("Expected to get an error. But now there isn't.")
return
}
str = "1,2|3"
data, err = StringToMap_Int32_Int32(str, seps)
if err == nil {
t.Errorf("Expected to get an error. But now there isn't.")
return
}
str = "1,2|3,abc"
data, err = StringToMap_Int32_Int32(str, seps)
if err == nil {
t.Errorf("Expected to get an error. But now there isn't.")
return
}
str = "1,2|a,3"
data, err = StringToMap_Int32_Int32(str, seps)
if err == nil {
t.Errorf("Expected to get an error. But now there isn't.")
return
}
str = "1,2|3,5"
data, err = StringToMap_Int32_Int32(str, seps)
if err != nil {
t.Errorf("Expected to get no error. But now there is one:%v.", err)
return
}
expected := make(map[int32]int32, 2)
expected[1] = 2
expected[3] = 5
if len(expected) != len(data) {
t.Errorf("The length of expected:%d is not equals to length of data:%d", len(expected), len(data))
return
}
for k, v := range data {
if v1, exists := expected[k]; !exists {
t.Errorf("data is not equals to expected. %v, %v", expected, data)
} else if v != v1 {
t.Errorf("data is not equals to expected. %v, %v", expected, data)
}
}
}
func TestStringToMap_Int32_Int64(t *testing.T) {
str := ""
seps := []string{",", "|"}
data, err := StringToMap_Int32_Int64(str, seps)
if err == nil {
t.Errorf("Expected to get an error. But now there isn't.")
return
}
str = "1,2|3"
data, err = StringToMap_Int32_Int64(str, seps)
if err == nil {
t.Errorf("Expected to get an error. But now there isn't.")
return
}
str = "1,2|3,abc"
data, err = StringToMap_Int32_Int64(str, seps)
if err == nil {
t.Errorf("Expected to get an error. But now there isn't.")
return
}
str = "1,2|a,3"
data, err = StringToMap_Int32_Int64(str, seps)
if err == nil {
t.Errorf("Expected to get an error. But now there isn't.")
return
}
str = "1,36524569852|3,365245698521"
data, err = StringToMap_Int32_Int64(str, seps)
if err != nil {
t.Errorf("Expected to get no error. But now there is one:%v.", err)
return
}
expected := make(map[int32]int64, 2)
expected[1] = 36524569852
expected[3] = 365245698521
if len(expected) != len(data) {
t.Errorf("The length of expected:%d is not equals to length of data:%d", len(expected), len(data))
return
}
for k, v := range data {
if v1, exists := expected[k]; !exists {
t.Errorf("data is not equals to expected. %v, %v", expected, data)
} else if v != v1 {
t.Errorf("data is not equals to expected. %v, %v", expected, data)
}
}
}