[Go语言系列] 12. Go 语言字符串操作

Go语言系列知识快速查看入口

:point_down::point_down::point_down:

本章内容

1 Like

12.1 字符串是否有某个前缀或后缀

函数签名

func HasPrefix(s, prefix string) bool
func HasSuffix(s, suffix string) bool

说明

HasPrefix - 判断字符串 s 中是否以 prefix 开始
HasSuffix - 判断字符串 s 中是否以 suffix 结尾
如果 prefix 或 suffix 为 "", 返回值总是true

示例

fmt.Println(strings.HasPrefix("Gopher", "Go"))
fmt.Println(strings.HasPrefix("Gopher", "C"))
fmt.Println(strings.HasPrefix("Gopher", ""))
fmt.Println(strings.HasSuffix("Amigo", "go"))
fmt.Println(strings.HasSuffix("Amigo", "Ami"))
fmt.Println(strings.HasSuffix("Amigo", ""))

输出

true
false
true
true
false
true
1 Like

12.2 是否存在某个字符或子串

函数签名

func Contains(s, substr string) bool
func ContainsAny(s, chars string) bool

说明

Contains - 子串substr在字符串s中,返回true
ContainsAny - chars中任意一个字符(Unicode Code Point)在字符串s中,返回true

示例

fmt.Println(strings.Contains("team", "ea"))
fmt.Println(strings.Contains("team", "li"))
fmt.Println(strings.ContainsAny("team", "i"))
fmt.Println(strings.ContainsAny("failure", "u&i"))
fmt.Println(strings.ContainsAny("in failure", "s g"))
fmt.Println(strings.ContainsAny("foo", ""))
fmt.Println(strings.ContainsAny("", ""))

输出

true
false
false
true
true
false
false
1 Like

12.3 字符或子串在字符串中出现的位置

(1)第一次出现的位置

函数签名

func Index(s, sep string) int
func IndexByte(s string, c byte) int
func IndexAny(s, chars string) int
func IndexFunc(s string, f func(rune) bool) int

说明

Index - 在 s 中查找 sep 的第一次出现,返回第一次出现的索引。
IndexByte - 在 s 中查找字节 c 的第一次出现,返回第一次出现的索引。
IndexAny - chars中任何一个 Unicode 代码点在 s 中首次出现的位置
IndexFunc - 查找字符 c 在 s 中第一次出现的位置,其中 c 满足 f(c) 返回true

示例

fmt.Println(strings.Index("hello world", "lo"))
fmt.Println(strings.IndexByte("hello world", 'o'))
fmt.Println(strings.IndexAny("hello world", "oks"))
	
han :=func(c rune) bool {
	return unicode.Is(unicode.Han, c)
}

fmt.Println(strings.IndexFunc("hello world", han))
fmt.Println(strings.IndexFunc("hello 世界", han))

输出

3
4
4
-1
6

(2)最后一次出现的位置

函数签名

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

说明

LastIndex - 在 s 中查找 sep 的第一次出现,返回最后一次出现的索引
LastIndexByte - 在 s 中查找字节 c 的第一次出现,返回最后一次出现的索引
LastIndexAny - chars 中任何一个 Unicode 代码点在 s 中最后一次出现的位置
LastIndexFunc - 查找字符 c 在 s 中最后一次出现的位置,其中 c 满足 f(c) 返回 true

示例

fmt.Println(strings.LastIndex("hello world", "lo"))
fmt.Println(strings.LastIndexByte("hello world", 'o'))
fmt.Println(strings.LastIndexAny("hello world", "oks"))

han := func(c rune) bool {
	return unicode.Is(unicode.Han, c)
}

fmt.Println(strings.LastIndexFunc("hello world", han))
// 最后一个汉字"界"出现的索引位置是9,因为在go中,一个汉字占三个字节
fmt.Println(strings.LastIndexFunc("hello 世界", han))

输出

3
7
7
-1
9
1 Like

12.4 字符串替换

进行字符串替换时,考虑到性能问题,能不用正则尽量别用,应该用这里的函数。

函数签名

func Replace(s, old, new string, n int) string
func ReplaceAll(s, old, new string) string

说明

Replace - 用new替换字符串s中的old,一共替换n个。如果 n<0,则不限制替换次数,
          即全部替换

ReplaceAll - 该函数内部直接调用了函数 Replace(s, old, new, -1)

示例

fmt.Println(strings.Replace("oink oink oink", "k", "ky", 2))
fmt.Println(strings.Replace("oink oink oink", "oink", "moo", -1))
fmt.Println(strings.ReplaceAll("oink oink oink", "oink", "moo"))

输出

oinky oinky oink
moo moo moo
moo moo moo
1 Like

12.5 统计子串出现的次数

函数签名

func Count(s, sep string) int

说明

查找子串出现次数。需要注意的是,当sep为空时,Count的返回值是:
utf8.RuneCountInString(s)+1

示例

fmt.Println(strings.Count("cheese", "e"))
fmt.Println(strings.Count("我爱你中国", ""))
// 注意:Count是计算子串在字符串中出现的无重叠的次数
fmt.Println(strings.Count("fivevev", "vev"))

输出

3
6
1
1 Like

12.6 字符串重复

函数签名

func Repeat(s string, count int) string

说明

将s重复count次,如果count为负数或返回值长度len(s)超出string上限会导致panic。

示例

fmt.Println(strings.Repeat("ba", 3))

输出

bababa

12.7 大小写转换

函数签名

func ToLower(s string) string
func ToUpper(s string) string

说明

ToLower - 转换为小写字母
ToUpper - 转换为大写字母

示例

fmt.Println(strings.ToLower("HELLO WORLD"))
fmt.Println(strings.ToUpper("hello world“))

输出

hello world
HELLO WORLD

12.8 字符串修剪

函数签名

// 将s左侧和右侧中匹配cutset中的任一字符的字符去掉
func Trim(s string, cutset string) string
// 将s左侧的匹配cutset中的任一字符的字符去掉
func TrimLeft(s string, cutset string) string
// 将s右侧的匹配cutset中的任一字符的字符去掉
func TrimRight(s string, cutset string) string
// 如果s的前缀为prefix则返回去掉前缀后的string,否则s没有变化
func TrimPrefix(s, prefix string) string
// 如果s的后缀为suffix则返回去掉后缀后的string,否则s没有变化
func TrimSuffix(s, suffix string) string
// 将s左侧和右侧的间隔符去掉。常见间隔符包括 '\t'、'\n'、'\v'、'\f'、'\r'、' '
func TrimSpace(s string) string
// 将s左侧和右侧的匹配f的字符去掉
func TrimFunc(s string, f func(rune) bool) string
// 将s左侧的匹配f的字符去掉
func TrimLeftFunc(s string, f func(rune) bool) string
// 将s右侧的匹配f的字符去掉
func TrimRightFunc(s string, f func(rune) bool) string

示例

x := "!!!@@@你好,!@#$ Gophers###$$$"

fmt.Println(strings.Trim(x, "@#$!%^&*()_+=-"))
fmt.Println(strings.TrimLeft(x, "@#$!%^&*()_+=-"))
fmt.Println(strings.TrimRight(x, "@#$!%^&*()_+=-"))
fmt.Println(strings.TrimSpace(" \t\n Hello, Gophers \n\t\r\n"))
fmt.Println(strings.TrimPrefix(x, "!"))
fmt.Println(strings.TrimSuffix(x, "$"))
f := func(r rune) bool {
    return !unicode.Is(unicode.Han, r) // 非汉字返回 true
}

fmt.Println(strings.TrimFunc(x, f))
fmt.Println(strings.TrimLeftFunc(x, f))
fmt.Println(strings.TrimRightFunc(x, f))

输出

你好,!@#$ Gophers
你好,!@#$ Gophers###$$$
!!!@@@你好,!@#$ Gophers
Hello, Gophers
!!@@@你好,!@#$ Gophers###$$$
!!!@@@你好,!@#$ Gophers###$$
你好
你好,!@#$ Gophers###$$$
!!!@@@你好

12.9 字符串分割

(1)Fields 和 FieldsFunc

函数签名

func Fields(s string) []string
func FieldsFunc(s string, f func(rune) bool) []string

说明

Fields     - 用一个或多个连续的空格分割字符串s,返回[]string。其中,空格的定义
             是unicode.IsSpace(判断一个字符是否为空格)。
             常见间隔符包括:'\t','\n','\v','\f','\r',' ',U+0085 (NEL),
             U+00A0 (NBSP) 

FieldsFunc - 用这样的代码点(unicode code points)进行分隔:满足f(c)返回true。
             如果字符串s中所有的代码点都满足f(c)或者s是空,则FieldsFunc返回空
             slice。

示例

fmt.Printf("Fields are: %q", strings.Fields("   foo  bar baz"))
fmt.Println(strings.FieldsFunc("  foo bar  baz   ", unicode.IsSpace))

输出

Fields are: ["foo" "bar" "baz"]
[foo bar baz]

(2)Split 和 SplitAfter、SplitN 和 SplitAfterN

函数签名

func Split(s, sep string) []string
func SplitAfter(s, sep string) []string
func SplitN(s, sep string, n int) []string
func SplitAfterN(s, sep string, n int) []string

说明

Split       - 通过sep分割,并将s中的sep去掉,返回[]string

SplitAfter  - 通过sep分割,但保留s中的sep,返回[]string

SplitN      - 通过sep分割,并将s中的sep去掉,通过最后一个参数n控制返回的结果中
              slice的元素个数。

SplitAfterN - 通过sep分割,但保留s中的sep,通过最后一个参数n控制返回的结果中
              slice的元素个数。

当n<0时,返回所有的子字符串;
当n=0时,返回的结果是nil;
当n>0时,返回的slice中最多只与n个元素,其中,最后一个元素不会分割。

示例

fmt.Printf("%q\n", strings.Split("foo,bar,baz", ","))
fmt.Printf("%q\n", strings.SplitAfter("foo,bar,baz", ","))
fmt.Printf("%q\n", strings.SplitN("foo,bar,baz", ",", -1))
fmt.Printf("%q\n", strings.SplitN("foo,bar,baz", ",", 0))
fmt.Printf("%q\n", strings.SplitN("foo,bar,baz", ",", 2))
fmt.Printf("%q\n", strings.SplitAfterN("foo,bar,baz", ",", 2))

输出

["foo" "bar" "baz"]
["foo," "bar," "baz"]
["foo" "bar" "baz"]
[]
["foo" "bar,baz"]
["foo," "bar,baz"]

12.10 字符串拼接

函数签名

func Join(a []string, sep string) string

说明

通过sep将字符串数组中的元素连接起来。

示例

fmt.Println(strings.Join([]string{"name=xxx", "age=xxx"}, "&"))

输出

name=xxx&age=xxx

12.11 标题处理

函数签名

func Title(s string) string
func ToTitle(s string) string

说明

Title - 将s每个单词的首字母大写,不处理该单词的后续字符。
ToTitle - 将s的每个字母大写。

示例

fmt.Println(strings.Title("hElLo wOrLd"))
fmt.Println(strings.ToTitle("hElLo wOrLd"))

输出

HElLo WOrLd
HELLO WORLD