Go语言之字符串处理

其他类型转字符串

在Go语言中,将其他类型转换为字符串通常使用strconv包中的函数。下面是一些常见类型到字符串的转换示例:

整数 => 字符串

整数类型转换为字符串,使用strconv.Itoa()fmt.Sprintf()函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package main

import (
"fmt"
"strconv"
)

func main() {
num := 42
str1 := strconv.Itoa(num)
fmt.Println("Using strconv.Itoa():", str1)

str2 := fmt.Sprintf("%d", num)
fmt.Println("Using fmt.Sprintf():", str2)
}

浮点数 => 字符串

浮点数类型转换为字符串,使用fmt.Sprintf()函数:

1
2
3
4
5
6
7
8
9
package main

import "fmt"

func main() {
floatNum := 3.14
str := fmt.Sprintf("%f", floatNum)
fmt.Println("Using fmt.Sprintf():", str)
}

布尔 => 字符串

布尔类型转换为字符串,直接使用布尔值进行字符串拼接:

1
2
3
4
5
6
7
8
9
package main

import "fmt"

func main() {
boolean := true
str := fmt.Sprintf("%t", boolean)
fmt.Println("Using fmt.Sprintf():", str)
}

字节数组 => 字符串

字节数组类型转换为字符串,使用string()类型转换:

1
2
3
4
5
6
7
8
9
package main

import "fmt"

func main() {
bytes := []byte{65, 66, 67}
str := string(bytes)
fmt.Println("Using string() conversion:", str)
}

结构体 => 字符串

结构体转字符串,常用于打印

1
parasStr := fmt.Sprintf("%+v", paras)

内存地址

指针的内存地址

1
objAddr := fmt.Sprintf("%p", conn)

字符串拼接

+拼接方式

这种方式是我在写golang经常用的方式,go语言用“+”拼接,不过由于golang中的字符串是不可变的类型,因此用 “+” 连接会产生一个新的字符串对效率有影响。

1
2
3
4
5
6
func main() {
s1 := "hello"
s2 := "word"
s3 := s1 + s2
fmt.Print(s3) //s3 = "helloword"
}

sprintf函数

1
2
3
s1 := "hello"
s2 := "word"
s3 := fmt.Sprintf("%s%s", s1, s2) //s3 = "helloword"

这种方式也是开发过程中经常使用到的,好处是不会直接产生临时字符串,但是效率好像也不是特别高。

Join函数

使用Join函数我们需要先引入strings包才能调用Join函数。Join函数会先根据字符串数组的内容,计算出一个拼接之后的长度,然后申请对应大小的内存,一个一个字符串填入,在已有一个数组的情况下,这种效率会很高,如果没有的话效率也不高。我一般用来切片转字符串使用。

1
2
3
4
5
s1 := "hello"
s2 := "word"
var str []string = []string{s1, s2}
s3 := strings.Join(str, "")
fmt.Print(s3)

strings.Builder函数

1
2
3
4
5
6
7
s1 := "hello"
s2 := "word"
var build strings.Builder
build.WriteString(s1)
build.WriteString(s2)
s3 := build.String()
fmt.Println(s3)

官方建议使用的拼接方式。

bytes.Buffer函数

1
2
3
4
5
6
7
s1 := "hello"
s2 := "word"
var bt bytes.Buffer
bt.WriteString(s1)
bt.WriteString(s2)
s3 := bt.String()
fmt.Println(s3)

总结

结论:

  • 在已有字符串数组的场合,使用 strings.Join() 能有比较好的性能。
  • 在一些性能要求较高的场合,尽量使用 strings.Builder 以获得更好的性能。
  • 性能要求不太高的场合,直接使用+,代码更简短清晰,能获得比较好的可读性。
  • 如果需要拼接的不仅仅是字符串,还有数字之类的其他需求的话,可以考虑 fmt.Sprintf()

总结:

strings.Join ≈ strings.Builder > bytes.Buffer > “+” > fmt.Sprintf

UUID

安装

1
go get github.com/google/uuid

使用

1
2
3
4
5
6
7
8
9
10
11
12
13
package main

import (
"fmt"
"github.com/google/uuid"
)

func main() {
// 生成新的 UUID
newUUID := uuid.New()

fmt.Println(newUUID.String())
}

字符串转小写

1
strings.ToLower(str)

路径拼接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package test

import (
"fmt"
"github.com/google/uuid"
"os"
"path"
"testing"
"time"
)

func TestPath(t *testing.T) {
dateStr := time.Now().Format("200601")
fmt.Println("dateStr", dateStr)

uuidStr := uuid.New().String()
fmt.Println("uuidStr", uuidStr)

pathStr := path.Join("static", "upload", dateStr, uuidStr)
fmt.Println("pathStr", pathStr)
err := os.MkdirAll(pathStr, os.ModePerm)
if err != nil {
return
}
}

字符串替换

替换路径中的\/

1
dirPath = strings.ReplaceAll(dirPath, "\\", "/")

替换第一个匹配到的字符串

1
filepath = strings.Replace(filepath, projectPath, "", 1)

日期格式化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package main

import (
"fmt"
"time"
)

func main() {
currentTime := time.Now()
fmt.Println("Current Time in String: ", currentTime.String())
fmt.Println("MM-DD-YYYY : ", currentTime.Format("01-02-2006"))
fmt.Println("YYYY-MM-DD : ", currentTime.Format("2006-01-02"))
fmt.Println("YYYY.MM.DD : ", currentTime.Format("2006.01.02 15:04:05"))
fmt.Println("YYYY#MM#DD {Special Character} : ", currentTime.Format("2006#01#02"))
fmt.Println("YYYY-MM-DD hh:mm:ss : ", currentTime.Format("2006-01-02 15:04:05"))
fmt.Println("Time with MicroSeconds: ", currentTime.Format("2006-01-02 15:04:05.000000"))
fmt.Println("Time with NanoSeconds: ", currentTime.Format("2006-01-02 15:04:05.000000000"))
fmt.Println("ShortNum Month : ", currentTime.Format("2006-1-02"))
fmt.Println("LongMonth : ", currentTime.Format("2006-January-02"))
fmt.Println("ShortMonth : ", currentTime.Format("2006-Jan-02"))
fmt.Println("ShortYear : ", currentTime.Format("06-Jan-02"))
fmt.Println("LongWeekDay : ", currentTime.Format("2006-01-02 15:04:05 Monday"))
fmt.Println("ShortWeek Day : ", currentTime.Format("2006-01-02 Mon"))
fmt.Println("ShortDay : ", currentTime.Format("Mon 2006-01-2"))
fmt.Println("Short Hour Minute Second: ", currentTime.Format("2006-01-02 3:4:5"))
fmt.Println("Short Hour Minute Second: ", currentTime.Format("2006-01-02 3:4:5 PM"))
fmt.Println("Short Hour Minute Second: ", currentTime.Format("2006-01-02 3:4:5 pm"))
}

结果

Current Time in String: 2021-04-15 11:33:49.7682761 +0800 CST m=+0.006808201
MM-DD-YYYY : 04-15-2021
YYYY-MM-DD : 2021-04-15
YYYY.MM.DD : 2021.04.15 11:33:49
YYYY#MM#DD {Special Character} : 2021#04#15
YYYY-MM-DD hh:mm:ss : 2021-04-15 11:33:49
Time with MicroSeconds: 2021-04-15 11:33:49.768276
Time with NanoSeconds: 2021-04-15 11:33:49.768276100
ShortNum Month : 2021-4-15
LongMonth : 2021-April-15
ShortMonth : 2021-Apr-15
ShortYear : 21-Apr-15
LongWeekDay : 2021-04-15 11:33:49 Thursday
ShortWeek Day : 2021-04-15 Thu
ShortDay : Thu 2021-04-15
Short Hour Minute Second: 2021-04-15 11:33:49
Short Hour Minute Second: 2021-04-15 11:33:49 AM
Short Hour Minute Second: 2021-04-15 11:33:49 am

字符串相关方法

比较和判断

比较和判断

  • Contains:判断字符串是否包含子串
  • HasPrefix:判断字符串是否以指定前缀开头
  • HasSuffix:判断字符串是否以指定后缀结尾
  • EqualFold:不区分大小写比较字符串是否相等

是否以什么开头

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package main

import (
"fmt"
"strings"
)

func main() {
str := "张三的电话号码是123456789"
prefix := "张"

if strings.HasPrefix(str, prefix) {
fmt.Printf("%s 是以 %s 开头的\n", str, prefix)
} else {
fmt.Printf("%s 不是以 %s 开头的\n", str, prefix)
}
}

包含

1
2
3
4
5
6
7
8
str := "Hello, world"
substr := "world"

if strings.Contains(str, substr) {
fmt.Printf("%s 包含 %s\n", str, substr)
} else {
fmt.Printf("%s 不包含 %s\n", str, substr)
}

查找和替换

查找和替换

  • Index:返回子串在字符串中首次出现的位置
  • LastIndex:返回子串在字符串中最后一次出现的位置
  • Replace:替换字符串中的子串

替换

1
2
3
4
5
6
str := "Hello, world"
oldSubstr := "world"
newSubstr := "Go"

newStr := strings.Replace(str, oldSubstr, newSubstr, -1)
fmt.Println(newStr)

拆分和连接

分割

1
2
3
4
5
6
str := "apple,banana,cherry"
words := strings.Split(str, ",")

for _, word := range words {
fmt.Println(word)
}

拼接

1
2
3
4
var nameList []string
nameList = append(nameList, "张三", "李四", "王五")
mStr := strings.Join(nameList, ",")
fmt.Println(mStr)

大小写

转大写/小写

1
2
3
4
5
6
str := "Hello, world"
upperStr := strings.ToUpper(str)
lowerStr := strings.ToLower(str)

fmt.Println(upperStr)
fmt.Println(lowerStr)

首字符转大写

1
2
3
str := "Hello, world"
titleStr := strings.Title(str)
fmt.Println(titleStr)

修剪和填充

修剪和填充

  • Trim:去掉字符串首尾指定字符
  • TrimSuffix:去掉字符串尾部指定后缀
  • Repeat:重复字符串指定次数作为新字符串