初识
一个字符串是一个不可改变的字节序列。文本字符串通常被解释为采用UTF8编码的Unicode码点(rune)序列。
- 内置的len函数
len函数可以返回一个字符串中的字节数目(不是rune字符数目),索引操作s[i]返回第i个字节的字节值
s := "hello, world"
fmt.Println(len(s)) // "12"
fmt.Println(s[0], s[7]) // "104 119" ('h' and 'w')
ss := "你好,世界"
fmt.Println(len(ss)) // "15" 每个汉字占三个字节
- 子字符串操作
fmt.Println(s[0:5]) // "hello"
对所有的字符串操作超出len(s)范围,会报panic异常
- 子字符串链接
fmt.Println(s[0:5] + " world") // "hello world"
-
字符串转义
双引号包含的字符串,可以用以反斜杠\开头的转义序列插入任意的数据。下面的换行、回
车和制表符等是常见的ASCII控制代码的转义方式:
\a 响铃
\b 退格
\f 换页
\n 换行
\r 回车
\t 制表符
\v 垂直制表符
’ 单引号 (只用在 ‘’’ 形式的rune符号面值中)
" 双引号 (只用在 “…” 形式的字符串面值中)
\ 反斜杠 -
反引号的用法
反引号 ` 包含的字符串中没有转义操作,全部都是字面意思。通常用于正则表达式和定义一个多行字符串。
s := `你好,世界
这里是go语言
`
fmt.Println(s) // “这里是go语言”会换行显示
- 字符串修改
字符串是不可变的,尝试直接修改字符串内部数据会报panic异常,需要先将字符串转换为[]byte类型
func changeString() {
s1 := "big"
// 强制类型转换
byteS1 := []byte(s1)
byteS1[0] = 'p'
fmt.Println(string(byteS1))
s2 := "白萝卜"
runeS2 := []rune(s2)
runeS2[0] = '红'
fmt.Println(string(runeS2))
}
字符串编码
Go语言的源文件采用UTF8编码,并且Go语言处理UTF8编码的文本也很出色。unicode包提供了诸多处理rune字符相关功能的函数(比如区分字母和数组,或者是字母的大写和小写转换等),unicode/utf8包则提供了用于rune字符序列的UTF8编码和解码的功能。
- 计算字符串中字符的个数
s := "hello,世界"
fmt.Println(utf8.RuneCountInString(s)) // 8
字符串和数字转换
- 字符串转整数
如果要将一个字符串解析为整数,可以使用strconv包的Atoi或ParseInt函数
ParseInt函数的第三个参数是用于指定整型数的大小;例如16表示int16,0则表示int。在任何情况下返回的结果y总是int64类型,你可以通过强制类型转换将它转为更小的整数类型。
x, err := strconv.Atoi("123") // x is an int
y, err := strconv.ParseInt("123", 10, 64) // base 10, up to 64 bits
- 数字转字符串
x := 123.33
y := fmt.Sprintf("%v", x)
fmt.Printf("%T\n", y) //string
fmt.Printf("%T\n", x) //float64
fmt.Println(y) // 123.33
比较重要的几个标准库
标准库中有四个包对字符串处理尤为重要:bytes、strings、strconv和unicode包。
字符串操作例子
- 字符串包含子串
func Contains(s, substr string) bool {
for i := 0; i < len(s); i++ {
if HasPrefix(s[i:], substr) {
return true
}
}
return false
}
- 字符串前缀和后缀
func HasPrefix(s, prefix string) bool {
return len(s) >= len(prefix) && s[:len(prefix)] == prefix
}
func HasSuffix(s, suffix string) bool {
return len(s) >= len(suffix) && s[len(s)-len(suffix):] == suffix
}
- 文件名称去除后缀
func basename(s string) string {
// Discard last '/' and everything before.
for i := len(s) - 1; i >= 0; i-- {
if s[i] == '/' {
s = s[i+1:]
break
}
}
// Preserve everything before last '.'.
for i := len(s) - 1; i >= 0; i-- {
if s[i] == '.' {
s = s[:i]
break
}
}
return s
}
或
func basename(s string) string {
slash := strings.LastIndex(s, "/") // -1 if "/" not found
s = s[slash+1:]
if dot := strings.LastIndex(s, "."); dot >= 0 {
s = s[:dot]
}
return s
}
- 实现每隔三个字符插入一个逗号
func comma(s string) string {
n := len(s)
if n <= 3 {
return s
}
return comma(s[:n-3]) + "," + s[n-3:]
}