Go 字符串

Go 字符串

  • 01 Go 字符串简介
  • 02 Go 支持的字面值
    • 1、解释字符串
    • 2、非解释字符串
  • 03 Go 字符串常用操作
    • 1、strings 包
      • (1)判断字符串的前缀和后缀
      • (2)判断字符串的包含关系
      • (3)判断子串出现的位置(索引)
      • (3)字符串替换
      • (4)统计字符串出现次数
      • (5)重复字符串
      • (6)修改字符串大小写
      • (7)修剪字符串
      • (8)分割字符串
      • (9)拼接 slice 到字符串
      • (10)从字符串中读取内容
    • 2、strconv 包
      • (1)数字类型转字符串类型
      • (2)字符串类型转数字类型

01 Go 字符串简介

  • Go 的字符串内部实现使用 UTF-8 编码,字符串是 UTF-8 字符的一个序列,当字符为 ASCII 码时则占用 1 个字节,其他字符根据需要占用 2-4 个字节。因此 Go 中的字符串里面的字符可能根据需要占用 1 至 4 个字节。Go 这样做的好处是① 减少内存和硬盘空间占用;② 不需要对使用 UTF-8 字符集的文本进行编码和解码

  • Go 的字符串的值为双引号""中的内容,可以直接在 Go 语言的源码中直接添加非 ASCII 码字符。

  • Go 的字符串是一种值类型且值不可变,即创建某个文本后无法对其进行修改。深入一点讲就是:字符串是字节的定长数组

  • Go 的字符串是根据长度限定,字符串类型的零值为长度为零的字符串,即空字符串""

  • 一般的比较运算符(==!=<<=>=>)通过在内存中按字节比较来实现字符串的对比

02 Go 支持的字面值

Go 支持以下 2 种形式的字面值:

1、解释字符串

该类字符串使用双引号括起来,其中相关的转义字符将被替换,转义字符有:

  • \n:换行符(直接跳到下一行的同列位置)
  • \r:回车符(返回行首)
  • \t:tab 键(制表符)
  • \':单引号
  • \":双引号
  • \\:反斜杠自身
  • \u\U:Unicode字符

2、非解释字符串

该类字符串使用反引号括起来,支持换行,可以用来定义多行字符串,例:

str := `第一行
第二行
第三行\n
`
fmt.Println(str)

该类字符串反引号间换行将被视为字符串中的换行,但是所有的转义字符均无效,按照原样输出

03 Go 字符串常用操作

Go 中使用 strings 包和 strconv 包完成对字符串的主要操作

1、strings 包

(1)判断字符串的前缀和后缀

  • HasPrefix 判断字符串 s 是否以某段字符串序列 prefix 开头(前缀):

    strings.HasPrefix(s, prefix string) bool

  • HasSuffix 判断字符串 s 是否以某段字符串序列 suffix 结尾(后缀):

    strings.HasSuffix(s, suffix string) bool

示例 1 :

package main

import (
	"fmt"
	"strings"
)

func main() {
	str := "llwwwhh" // 声明字符串 str
    
    // 判断字符串 str 是否存在前缀 ll, 返回一个 bool 类型的值
	pre := strings.HasPrefix(str, "ll") 
    // 判断字符串 str 是否存在后缀 ww, 返回一个 bool 类型的值
	suf := strings.HasSuffix(str, "hh") 
	
    if pre {
		fmt.Println("pre is exist.")
	} else {
		fmt.Println("pre is not exist.")
	}
	if suf {
		fmt.Println("suf is exist.")
	} else {
		fmt.Println("suf is not exist.")
	}
}

输出:

pre is exist.
suf is exist.

(2)判断字符串的包含关系

Contains 判断字符串 str 是否包含某段字符串序列 substr

strings.Contains(str, substr string) bool

示例 2:

package main

import (
	"fmt"
	"strings"
)

func main() {
	str := "llwwwhh" // 声明字符串 str
	
	// 判断字符串 str 是否包含 ww, 返回一个 bool 类型的值
	flag := strings.Contains(str, "ww")
	
	if flag {
		fmt.Println("str contains ww.")
	} else {
		fmt.Println("str does not contains ww.")
	}
}

输出:

str contains ww.

(3)判断子串出现的位置(索引)

判断子字符串或字符在父字符串中出现的位置(索引):

  • Index 返回字符串 s 在字符串 str 中的索引(s 的第一个字符的索引),-1 表示字符串 s 不包含字符串 str

    strings.Index(str, s string) int

  • LastIndex 返回字符串 s 在字符串 str 中最后出现位置的索引(s 的第一个字符的索引),-1 表示字符串 str 不包含字符串 s

    strings.LastIndex(str, s string) int

  • 如果需要查询非 ASCII 编码的字符在字符串中的位置,建议使用以下函数来对字符进行定位:

    strings.IndexRune(str string, r rune) int

注意:

  • 该方法在最新版本的 Go 中定义为 func IndexRune(s string, r rune) int

  • 实际使用中的第二个参数 rune 可以是 rune 或 int,如 strings.IndexRune(“chicken”, 99) 或 strings.IndexRune(“chicken”, rune(‘k’))

示例 3:

package main

import (
	"fmt"
	"strings"
)

func main() {
	str := "llwwwhh" // 声明字符串 str
	s := "ww" // 声明字符串 s
	// 返回字符串 s 在字符串 str 中的索引
	index := strings.Index(str, s)
	// 返回字符串 s 在字符串 str 中最后出现位置的索引
	lastIndex := strings.LastIndex(str, s)
	fmt.Println(index)
	fmt.Println(lastIndex)
}

输出:

2
3

(3)字符串替换

Replace 用于将字符串 str 中的前 n 个字符串 old 替换为新字符串 new,并返回一个新的字符串,如果 n = -1 则替换所有字符串 old 为新字符串 new

strings.Replace(str, old, new, n) string

示例:

package main

import (
	"fmt"
	"strings"
)

func main() {
	str := "llwwwhh" // 声明字符串 str
	// 替换字符串中前2个"ll"字符串为新字符串"LL"
	newStr := strings.Replace(str, "ll", "LL", 2)
	fmt.Println(newStr)
}

输出:

LLwwwhh

(4)统计字符串出现次数

Count 用于计算字符串 s 在字符串 str 中出现的非重叠次数:

strings.Count(str, s string) int

示例:

package main

import (
	"fmt"
	"strings"
)

func main() {
	// 声明一个字符串 str
	str := "You are the apple of my eye."
	// 声明一个字符串 s
	s := "a"
	// 计算字符串 s 在字符串 str 中出现的非重叠次数
	aCount := strings.Count(str, s)
	fmt.Println(aCount)
}

输出:

2

(5)重复字符串

Repeat 用于重复 count 次字符串 str 并返回一个新的字符串:

strings.Repeat(str, count int) string

示例:

package main

import (
	"fmt"
	"strings"
)

func main() {
	// 声明一个字符串 str
	str := "Come here!"
	// 声明一个int整型 count
	count := 3
	// 使字符串 str 重复出现 count 次,返回一个新字符串
	newStr := strings.Repeat(str, count)
	fmt.Println(newStr)
}

输出:

Come here!Come here!Come here!

(6)修改字符串大小写

  • ToLower 将字符串中的 Unicode 字符全部转换成相应的小写字符:

    strings.ToLower(str) string

  • ToUpper 将字符串中的 Unicode 字符全部转换为相应的大写字符:

    strings.ToUpper(str) string

示例:

package main

import (
	"fmt"
	"strings"
)

func main() {
	// 声明一个字符串 str1
	str1 := "I LIKE YOU."
	// 声明一个字符串 str2
	str2 := "i love you."
	// 将字符串 str1 的大写字母全部转为小写字母
	lowerStr := strings.ToLower(str1)
	// 将字符串 str2 的小写字母全部转为大写字母
	uppperStr := strings.ToUpper(str2)
	fmt.Println(lowerStr)
	fmt.Println(uppperStr)
}

输出:

i like you.
I LOVE YOU.

(7)修剪字符串

  • TrimSpace 可以剔除字符串 str 开头和结尾的空白符号

    strings.TrimSpace(str)

  • Trim 可以剔除字符串 str 开头和结尾的指定字符串 s,第二个参数可以是任何字符

    strings.Trim(str, s string)

  • TrimLeft 可以只剔除开头的字符串 s

    strings.TrimLeft(str, s string)

  • TrimRight 可以只剔除结尾的字符串 s

    strings.TrimRight(str, s string)

示例:

package main

import (
	"fmt"
	"strings"
)

func main() {
	// 1、剔除字符串开头和结尾的空白符号
	// 声明一个字符串 str
	str1 := " a=1,b=2,c=3,d=4 "
	// 剔除字符串 str 开头和结尾的空白符号
	newStr1 := strings.TrimSpace(str1)
	fmt.Println("str1:" + str1 + "结束--")
	fmt.Println("newStr1:" + newStr1 + "结束--")

	// 2、剔除字符串开头和结尾的指定字符
	// 声明一个字符串 str2
	str2 := "cutLWHcut"
	// 声明一个字符串 s,也是要从字符串str2中剔除的指定字符
	s := "cut"
	// 剔除字符串 str2 开头和结尾的指定字符 s
	newStr2 := strings.Trim(str2, s)
	fmt.Println("str2:" + str2)
	fmt.Println("newStr2:" + newStr2)

	// 3、只剔除字符串开头的字符
	str3 := "comeHOWcome"
	newStr3 := strings.TrimLeft(str3, "come")
	fmt.Println("str3:" + str3)
	fmt.Println("newStr3:" + newStr3)

	// 4、只剔除字符串结尾的字符
	str4 := "comeHOWcome"
	newStr4 := strings.TrimRight(str4, "come")
	fmt.Println("str4:" + str4)
	fmt.Println("newStr4:" + newStr4)
}

输出:

str1: a=1,b=2,c=3,d=4 结束--
newStr1:a=1,b=2,c=3,d=4结束--
str2:cutLWHcut
newStr2:LWH
str3:comeHOWcome
newStr3:HOWcome
str4:comeHOWcome
newStr4:comeHOW

(8)分割字符串

  • Fileds 会利用 1 个或多个空白符号来作为动态长度的分隔符将字符串 str分割成若干小块,并返回一个 slice,如果字符串只包含空白符号,则返回一个长度为 0 的 slice

    strings.Fields(str)

  • Split 用于自定义分割符号 sep 来对指定字符串 str 进行分割,同样返回 slice

    strings.Split(str, sep)

这两个函数都会返回 slice,所以习惯使用 for-range 循环对其进行处理

示例:

package main

import (
	"fmt"
	"strings"
)

func main() {
	// 1、利用 1 个或多个空白符号来作为动态长度的分隔符将字符串 str 分割成若干小块,返回 slice
	// 声明一个字符串 str1
	str1 := "t l j  swhi "
	// 分割字符串 str1 
	slice1 := strings.Fields(str1)
	fmt.Println("slice1:")
	// for-range 遍历 slice1 输出 
	for _, value1 := range slice1 {
		fmt.Println(value1)
	}

	// 2、使用自定义分割符号 sep 来对指定字符串 str 进行分割,返回 slice
	// 声明一个字符串 str2
	str2 := "a=1, b=2, c=3, d=4"
	// 自定义分割符号 sep
	sep := ","
	// 以 sep 分割字符串 str2
	slice2 := strings.Split(str2, sep)
	fmt.Println("\nslice2:")
	// for-range 遍历 slice2 输出 
	for _, value2 := range slice2 {
		fmt.Println(value2)
	}
}

输出:

slice1:
t
l
j
swhi

slice2:
a=1
 b=2
 c=3
 d=4

(9)拼接 slice 到字符串

Join 用于将元素类型为 stringslice 使用分割符号 sep 拼接组成一个字符串:

strings.Join(sl []string, sep string) string

示例:

package main

import (
	"fmt"
	"strings"
)

func main() {
	// 声明一个字符串 str
	str1 := "Go|The Way to Go|Effective Go"
	// 自定义分割符号 sep1
	sep1 := "|"
	// 以 sep1 分割字符串 str1
	sl1 := strings.Split(str1, sep1)
	fmt.Println("sl1:")
	// for-range 遍历 sl1 输出
	for _, value := range sl1 {
		fmt.Println(value)
	}
	fmt.Println()
	// 自定义分割符号 sep2
	sep2 := ";"
	// 将元素类型为 string 的 slice 使用分隔符号 sep2 拼接组成字符串
	str2 := strings.Join(sl1, sep2)
	fmt.Println(str2)
}

输出:

sl1:
Go
The Way to Go
Effective Go

Go;The Way to Go;Effective Go

(10)从字符串中读取内容

NewReader 用于生成一个 Reader 并读取字符串 str 中的内容,然后返回指向该 Reader 的指针

strings.NewReader(str)

从其他类型读取内容的函数还有:

  • Read()[]byte 中读取内容
  • ReadByte()ReadRune() 从字符串中读取下一个 byte 或者 rune

2、strconv 包

strconv 包实现了基本数据类型与其字符串表示的转换,主要有以下常用函数:Atoi()、Itia()、parse系列、format系列、append系列,该包还包含了一些变量用于获取程序运行的操作系统平台下 int 类型所占的位数,如:strconv.IntSize

(1)数字类型转字符串类型

任何类型 T 转换为字符串总是成功的

  • Itoa用于将 int 类型数据转换为对应的字符串表示:

    strconv.Itoa(i int) string

    也就是返回数字 i 所表示的字符串类型的十进制数

    【扩展】a 的典故:C 语言中没有 string 类型而是用字符数组(array)表示字符串

  • FormatFloat 用于将 64 位浮点型的数字转换为字符串,其中 fmt 表示格式(其值可以是 befg),prec 表示精度,bitSize 使用 32 表示 float32,用 64 表示 float64

(2)字符串类型转数字类型

将字符串转换为其他类型 T 并不总是可能的,可能会在运行时抛出错误 parsing "...": invalid argument

  • Atoi 用于将字符串类型的整数转换为 int 类型:

    strconv.Atoi(s string) (i int, err error)

  • ParseFloat 用于将字符串转换为 float64 类型:

    strconv.ParseFloat(s string, bitSize int) (f float64, err error)

    bitSize 使用 32 表示 float32,用 64 表示 float64

这些函数都会返回 2 个值,第 1 个是转换后的结果(如果转换成功),第 2 个是可能出现的错误,因此,一般使用以下形式进行从字符串到其它类型的转换:

val, err = strconv.Atoi(s)

你可能感兴趣的:(Golang,golang,开发语言,后端,go字符串,Go字符串操作)