字符串操作

目录

本文列举关于字符串最常用的几个操作,都会举例说明

字符串相关操作需要导入包strings

字符串长度

  • len()
1
2
3
4
5
func strLength() {
var str = "abc"
var length = len(str)
fmt.Println(length)
}

查找

  • func Contains(s, substr string) bool 子串substr在s中,返回true
  • func ContainsAny(s, chars string) bool chars中任何一个字符在s中,返回true
  • func ContainsRune(s string, r rune) bool Unicode代码点r在s中,返回true
  • func Count(s, sep string) int sep 在s中重复出现的次数(不计算重叠)
  • func Index(s, sep string) int 在字符串s中查找sep所在的位置, 找不到返回-1

在Go中,查找子串出现次数即字符串模式匹配,实现的是Rabin-Karp算法。
另外,Count 是计算子串在字符串中出现的无重叠的次数

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
29
30
31
32
33
34
35
36
func existSubStringOrChar() {

var super = "abcdef!"
var suba = "abc"
var subb = "ef!"

var hasa = existSubString(super, suba)
var hasb = existSubChar(super, subb)

fmt.Println(hasa, hasb)

var s = "fivevev"
var sep1 = "vev"
var sep2 = "adfd"

var c1 = repeatCount(s, sep1)
var c2 = repeatCount(s, sep2)
fmt.Println(c1, c2)

}

// 是否存在某个字符或子串
func existSubString(superString string, substring string) bool {
return strings.Contains(superString, substring)

}

//substring 是否含有superString 的任意一个字符
func existSubChar(superString string, substring string) bool {
return strings.ContainsAny(superString, substring)
}

//substring 的重复出现次数
func repeatCount(superString string, substring string) int {
return strings.Count(superString, substring)
}

结果

1
2
true true
1 0

替换

  • strings.Replace(s, old, new, n)

s需要替换的字符串 old需要被替换掉的某个子串 new替换的值
n n<0全部替换 n==0不替换 n>0全部替换 如果n的下标匹配上old值,则只替换当前下标的字符,如果不是,则全部替换

1
2
3
4
5
6
7
8
9
10
11
func strReplace() {

var str = "cabcdefgabc"
var value = strings.Replace(str, "a", "v", -1)
var value1 = strings.Replace(str, "a", "v", 0)
var value2 = strings.Replace(str, "a", "v", 1)
var value3 = strings.Replace(str, "a", "v", 3)

fmt.Println(value, value1, value2, value3)
strings.Replace(s, old, new, n)
}

结果

1
cvbcdefgvbc cabcdefgabc cvbcdefgabc cvbcdefgvbc

分割

Fields 和 FieldsFunc

  • Fields 按空格切割
  • FieldsFunc 按照自己指定的方式切割

实际上,Fields 函数就是调用 FieldsFunc 实现的:

1
2
3
func Fields(s string) []string {
return FieldsFunc(s, unicode.IsSpace)
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
func strCut() {

var str = "abc bde efg"

var cut1 = strings.Fields(str)

var cut2 = strings.FieldsFunc(str, unicode.IsSpace)

fmt.Println(cut1, cut2)

s := "ab*cd*ef"
result := strings.FieldsFunc(s, func(c rune) bool {
if c == 'h' {
return true
}
return false
})
fmt.Println(result)

}

结果

1
2
[abc bde efg] [abc bde efg]
[ab*cd*ef]

Split 和 SplitAfter、 SplitN 和 SplitAfterN

1
2
3
4
func Split(s, sep string) []string { return genSplit(s, sep, 0, -1) }
func SplitAfter(s, sep string) []string { return genSplit(s, sep, len(sep), -1) }
func SplitN(s, sep string, n int) []string { return genSplit(s, sep, 0, n) }
func SplitAfterN(s, sep string, n int) []string { return genSplit(s, sep,len(sep), n)}

它们都调用了 genSplit 函数。
这四个函数都是通过 sep 进行分割,返回[]string。如果 sep 为空,相当于分成一个个的 UTF-8 字符,如 Split(“abc”,””),得到的是[a b c]。

功能区分:after 会保留分隔符
1
2
fmt.Printf("%q\n", strings.Split("foo,bar,baz", ","))
fmt.Printf("%q\n", strings.SplitAfter("foo,bar,baz", ","))

输出:

1
2
["foo" "bar" "baz"]
["foo," "bar," "baz"]

N的区别

N 用来控制分割的个数
当 n < 0 时,返回所有的子字符串;当 n == 0 时,返回的结果是 nil;当 n > 0 时,表示返回的 slice 中最多只有 n 个元素,其中,最后一个元素不会分割

fmt.Printf("%q\n", strings.SplitN("foo,bar,baz", ",", 2))
输出:
["foo" "bar,baz"]

另外看一下官方文档提供的例子,注意一下输出结果:

1
2
3
4
fmt.Printf("%q\n", strings.Split("a,b,c", ","))
fmt.Printf("%q\n", strings.Split("a man a plan a canal panama", "a "))
fmt.Printf("%q\n", strings.Split(" xyz ", ""))
fmt.Printf("%q\n", strings.Split("", "Bernardo O'Higgins"))

输出:

1
2
3
4
["a" "b" "c"]
["" "man " "plan " "canal panama"]
[" " "x" "y" "z" " "]
[""]

split总结

关于字符串的分割,最常用的就是Split,其他几乎用不到

合并

将字符串数组(或slice)连接起来可以通过 Join 实现

  • func Join(a []string, sep string) string
1
2
3
4
5
6
7
8
func strJoin() {
var arr = []string{"a", "b", "c"}
fmt.Println(arr)
// 用 ‘-’ 拼接
fmt.Println(strings.Join(arr, "-"))
// 直接拼接
fmt.Println(strings.Join(arr, ""))
}

输出:

1
2
3
[a b c]
a-b-c
abc

前缀或后缀

1
2
3
4
5
6
7
8
9
10
11
12
func presuf() {

var str = "abcdefg"
//判断开始
var preA = strings.HasPrefix(str, "a")

//判断结尾
var preG = strings.HasSuffix(str, "g")

fmt.Println(preA, preG)

}

输出:
true true

截取

1
2
3
4
5
6
7
8
func subString() {
//strings 没有 截取字符串的方法
var str = "abc中国defgh"
// 将str转为切片处理 这里最好不用byte,byte不支持中文,unicode等
var strArr = string([]rune(str)[:4])

fmt.Println(strArr)
}

输出:

1
abc中

删除

strings 包中没有提供删除的方法,只能自己实现

1
2
3
4
5
6
7
8
func deleteStrWithRange(s string, start int, end int) string {
if len(s) == 0 || end > len(s) {
return ""
}
var str1 = string([]rune(s)[:start])
var str2 = string([]rune(s)[end:])
return str1 + str2
}
1
2
var sss = deleteStrWithRange("012345678", 1, 3)
fmt.Println(sss)

输出:
0345678

插入

go strings 包没有插入方法,只能将字符串转化为切片,然后插入元素,再转为string

编码转换

字符串转换需要用到 strconv

  • Append 函数表示将给定的类型(如bool, int等)转换为字符串后, 添加在现有的字节数组中[]byte
  • Format 函数将给定的类型变量转换为string返回
  • Parse 函数将字符串转换为其他类型

unicode 与 中文 互转

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
func chinaeseToUnicode() {
sText := "中文"
textQuoted := strconv.QuoteToASCII(sText)
fmt.Println(textQuoted)

textUnquoted := textQuoted[1 : len(textQuoted)-1]
fmt.Println(textUnquoted)

sUnicodev := strings.Split(textUnquoted, "\\u")
var context string
for _, v := range sUnicodev {
if len(v) < 1 {
continue
}
temp, err := strconv.ParseInt(v, 16, 32)
if err != nil {
panic(err)
}
context += fmt.Sprintf("%c", temp)
}
fmt.Println(context)
}

输出

1
2
3
"\u4e2d\u6587"
\u4e2d\u6587
中文

转码与解码

需要导入包 net/url

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
func encodeAndDecode() {
var str = "https://www.baidu.com/生活"

//转码
var encode = url.QueryEscape(str)

fmt.Println(encode)

//解码
decodeurl, err := url.QueryUnescape(encode)
if err != nil {
panic(err)
}
fmt.Println(decodeurl)
}

输出

1
2
https%3A%2F%2Fwww.baidu.com%2F%E7%94%9F%E6%B4%BB
https://www.baidu.com/生活

转换数值类型

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
func strToValue() {

// int 转 string
var intA int = 123
var stringA string = strconv.Itoa(intA)
fmt.Println(stringA, reflect.TypeOf(stringA))

// string 转 int

var stringB = "45678"
intB, err := strconv.Atoi(stringB)
if err != nil {
panic(err)
}
fmt.Println(intB, reflect.TypeOf(intB))

// string to float
var stringc = "123.45678"
floatC, err := strconv.ParseFloat(stringc, 32) //bitSize:指定浮点类型(32:float32、64:float64,
if err != nil {
panic(err)
}
fmt.Println(floatC, reflect.TypeOf(floatC))

}

输出

1
2
3
123 string
45678 int
123.45678 float64

大小写转换

1
2
3
4
5
6
7
8
// 给定字符串转换为英文标题的首字母大写的格式(不能正确处理unicode标点)
func Title(s string) string

// 所有字母转换为小写
func ToLower(s string) string

// 所有字母转换为大写
func ToUpper(s string) string
1
2
3
4
5
fmt.Println(strings.Title("her royal highness"))  // Her Royal Highness

fmt.Println(strings.ToLower("Gopher123")) // gopher123

fmt.Println(strings.ToUpper("Gopher")) // GOPHER

Trim操作

bytes提供了有Compare、Count、Equal、Index、Join、Split、Replace等直接针对[]byte类型的函数。还有一个重要的Buffer类,将[]byte类型当作一个缓冲区,提供了对这个缓冲区便捷的操作:读、写、和string/rune之间的转换、迭代等函数。

在bytes库中,有Trim系列的函数,它的功能是对[]byte类型做裁剪,去除不需要的部分。

  • func Trim(s string, cutset string) string 去除两边自定义字符
  • func TrimFunc(s string, f func(rune) bool) string 自定义清除
  • func TrimLeft(s string, cutset string) string 清除左边
  • func TrimPrefix(s, prefix string) string 删除前缀
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
func strtrim() {
var str = " ads!/ ;' jha asdfhj "

// 去除首尾空格,一般这个最常用
var value1 = strings.Trim(str, " ")
fmt.Println(value1)

//自定义trim
fmt.Println(strings.TrimFunc("&&&&nihao&&&&", func(r rune) bool {
if r == '&' {
return true
}
return false
}))

//trim 左侧 & 右侧
fmt.Println(strings.TrimLeft("&&&&nihao&&&&", "&"))
fmt.Println(strings.TrimRight("&&&&nihao&&&&", "&"))

//去除前缀,后缀也一样
var str2 = "xxx_abcd"
if strings.HasPrefix(str2, "xxx_") {
fmt.Println(strings.TrimPrefix(str2, "xxx_"))
}
}

输出:

1
2
3
4
5
ads!/  ;'  jha   asdfhj
nihao
nihao&&&&
&&&&nihao
abcd

ASCII 转换

1
2
3
4
5
6
7
8
9
10
11
12
func strASCII() {

//字符转ASCII
var c rune = 'a'
var i1 = int(c)
fmt.Println("'a' convert to ASCII", i1)

//ASCII 转字符
var i int = 98
var c1 = rune(i)
fmt.Println("98 convert to string", string(c1))
}

输出

1
2
'a' convert to ASCII 97
98 convert to string b

字符串重复几次

  • func Repeat(s string, count int) string
1
2
3
func strRepeatCount() {
fmt.Println(strings.Repeat("a", 2))
}

输出

aa

字符或子串在字符串中首次出现的位置或最后一次出现的位置

4个查找第一次出现的位置

// 在 s 中查找 sep 的第一次出现,返回第一次出现的索引
func Index(s, sep string) int
// chars中任何一个Unicode代码点在s中首次出现的位置
func IndexAny(s, chars string) int
// 查找字符 c 在 s 中第一次出现的位置,其中 c 满足 f(c) 返回 true
func IndexFunc(s string, f func(rune) bool) int
// Unicode 代码点 r 在 s 中第一次出现的位置
func IndexRune(s string, r rune) int

一般用indexAny

3个查找最后一次出现的位置

func LastIndex(s, sep string) int
func LastIndexAny(s, chars string) int
func LastIndexFunc(s string, f func(rune) bool) int

一般用LastIndexAny就行

坚持原创技术分享,您的支持将鼓励我继续创作!