Golang基础笔记二之字符串及其操作
本文首发于公众号:Hunter后端
原文链接:Golang基础笔记二之字符串及其操作
这一篇笔记主要介绍 Golang 字符串相关处理,以下是本篇笔记目录:
- 字符串的定义和初始化
- 字符
- 字符串操作
1、字符串的定义和初始化
在 Go 里,我们可以使用双引号和反引号来对定义字符串。
1. 双引号
双引号用于创建解释型字符串字面量,这种字符串是支持转义字符的,比如我们在字符串中夹带换行符 \n,这样在输出的时候,会自动进行换行:
s := "this is a test\nthis is another test"
fmt.Print(s)
// this is a test
// this is another test
2. 反引号
反引号用于创建原生字符串字面量,这种字符串中,所有字符都会按原样输出,转移字符不会被解释:
s := `this is a test\nthis is another test`
fmt.Print(s)
// this is a test\nthis is another test
2、字符
字符串是由一个个字符组合而成的,前面介绍过,Go 里字符有两种类型 byte 和 rune,但他们实际上分别是 uint8 和 int32 的别名,分别用于表示 ASCII 字符和 Unicode 字符。
每一个 byte 字符用一个字节(8位)来表示,每一个 rune 字符用 1-4 个字节来表示,如果我们想统计一个字符串的长度,首先需要判断我们是想统计其字节长度,还是字符长度。
因为对于一个字符串来说,如果字符串中包含了类似中文这种一个字符包含多个字节的字符,其字节长度和字符长度是不一样的,比如对于下面的字符串:
s := "hello世界"
对于前面的 hello 来说,一个字符就包含一个字节,所以它的字符长度是 5,字节长度也是 5。
而对于后面的 世界 来说,一个字符包含三个字节,所以它的字符长度是 2,但是字节长度是 2 * 3 = 6。
所以这个字符串的字节长度和字符串长度分别如下:
s := "hello世界"
fmt.Println("s 的字节长度为:", len(s)) // 11
fmt.Println("s 的字符串长度为:", len([]rune(s))) // 7
在统计字符串长度的时候,我们先将其转为了 rune 类型的切片,然后再统计的其长度。
3、字符串操作
1. 字符串拼接
字符串的拼接可以用两种方式,一种是使用 +,一种是使用 strings.Builder
1) +运算符
s1 := "hello"
s2 := " world"
s3 := s1 + s2
fmt.Println(s3)
2) strings.Builder
import (
"strings"
"fmt"
)
func main() {
var builder strings.Builder
builder.WriteString("hello")
builder.WriteString(" world")
s := builder.String()
fmt.Println(s)
}
+运算符和 strings.Builder 都可以用于拼接字符串,但是在 Go 语言里,字符串属于不可变类型,每次使用 + 运算符拼接字符串时,都会创建一个新的字符串对象。
如果频繁拼接大量字符串,会产生大量的内存分配和数据复制操作,导致性能较低。
strings.Builder 内部维护了一个字节切片,在拼接字符串时,会先将字符串追加到这个字节切片中,最后再将字节切片转换为字符串。这样可以减少内存分配和数据复制的次数,性能更高。
2. 字符串的访问
如果想访问字符串中的单个字符,可以使用下标来操作:
s := "hello"
fmt.Println(s[4]) // 111
我们可以对其进行格式化,使用 %c 来打印:
fmt.Printf("%c\n", s[4]) // o
前面介绍字符串长度的时候,字符串是由字符组成的,但是因为这里测试字符串是全英文的,所以访问到的这个字符就是它的字节内容。
如果字符串包含中文,使用 len() 函数获取到的长度实际上是它的字节长度。
比如下面这个例子,我们访问到的就是字符串对应下标的字节内容,而不是对应的字符了:
s := "hello世界"
fmt.Println(s[5]) // 228
fmt.Printf("%c\n", s[5]) // ä
若要按字符访问带中文的字符串,可以将字符串转换为 []rune 类型,因为 rune 类型可以表示一个 Unicode 字符:
s := "hello世界"
fmt.Printf("%c\n", []rune(s)[5]) // 世
fmt.Printf("%c\n", []rune(s)[6]) // 界
遍历访问字符串
如果要遍历访问字符串,可以按照前面的操作先将其转为 rune 切片,然后再遍历访问 rune 切片:
s := "hello世界"
runes := []rune(s)
for _, c := range runes {
fmt.Printf("%c\n", c)
}
还可以使用 for...range 循环,它可以按字符迭代字符串,会自动处理 UTF-8 编码的多字节字符:
s := "hello世界"
for _, char := range s {
fmt.Printf("%c\n", char)
}
3. 字符串查找
我们可以引入 strings 模块使用 strings.Index() 来查找指定字符串,返回的是该字符串的字节索引,如果没有找到,则返回 -1。
s := "hello世界"
index := strings.Index(s, "界")
fmt.Println(index) // 8
index2 := strings.Index(s, "好")
fmt.Println(index2) // -1
4. 字符串替换
我们可以使用 strings.Replace() 来替换字符串。
str := "hello世界"
s2 := strings.Replace(str, "l", "x", 1)
fmt.Println(s2)
在上面的操作中,表示将字符串 str 中的 l 字符串替换为 x,并且只替换第一个 l。
如果需要替换多个,则可以将后面的数字 1 改成指定个数。
如果想要将字符串中指定字符串全部替换,可以将最后一个参数设置为 -1。
也可以使用 strings.ReplaceAll() 来替换字符串:
str := "hello世界"
s2 := strings.Replace(str, "l", "x", -1)
fmt.Println(s2)
s3 := strings.ReplaceAll(str, "l", "x")
fmt.Println(s3)
5. 字符串分割
我们可以使用 strings.Split() 来进行字符串分割:
s := "hello,世界,我来了"
parts := strings.Split(s, ",")
fmt.Println(parts)
返回的 parts 就是一个字符串切片。
还可以使用 strings.SplitN() 对其进行指定长度的切割,比如只需要将其切割成两部分:
s := "hello,world"
parts := strings.SplitN(s, "o", 2)
fmt.Println(parts, len(parts)) // [hell ,world] 2
注意:这里的参数 2 指的是最终切割后生成的切片长度,如果 n 超过字符串可以切割的长度,则会根据指定字符串其全部切割并返回结果。
所以如果 n 参数为 1,则不会切割,返回原始结果,如果 n 参数为 0,则会返回 nil,如果 n 是负数,则会全部切割。
6. 字符串是否以字符串开头或结尾
strings.HasPrefix() 表示是否是以某字符串开头,返回 bool 型结果。
strings.HasSuffix() 表示是否是以某字符串结尾,返回 bool 型结果。
s := "世界hello,world"
result := strings.HasPrefix(s, "世界")
fmt.Println(result)
result2 := strings.HasSuffix(s, "world")
fmt.Println(result2)
7. 是否包含某字符串
strings.Contains() 用于判断字符串是否包含某个特定字符串,返回结果为布尔型。
s := "hello, world"
isContain := strings.Contains(s, "world")
fmt.Println(isContain)
8. 字符串统计包含子字符串个数
strings.Count() 用于统计字符串中包含某个特定字符串的个数。
s := "hello, world"
l_count := strings.Count(s, "l")
fmt.Println(l_count)
9. 转大小写
strings.ToUpper() 表示将字符串转为大写
strings.ToLower() 表示将字符串转为小写
s := "hello, world"
upperS := strings.ToUpper(s)
fmt.Println(upperS)
lowerS := strings.ToLower(s)
fmt.Println(lowerS)
10. 去除首尾指定字符串
strings.Trim() 去除字符串左右两边指定的字符串
strings.TrimLeft() 去除字符串左边指定的字符串
strings.TrimRight() 去除字符串右边指定的字符串
s := "ihello, worldi"
result := strings.Trim(s, "i")
fmt.Println(result) // hello, world
result = strings.TrimLeft(s, "i")
fmt.Println(result) // hello, worldi
result = strings.TrimRight(s, "i")
fmt.Println(result) // ihello, world
如果想获取更多相关文章,可扫码关注阅读:

Golang基础笔记二之字符串及其操作的更多相关文章
- JavaScript基础笔记二
一.函数返回值1.什么是函数返回值 函数的执行结果2. 可以没有return // 没有return或者return后面为空则会返回undefined3.一个函数应该只返回一种类型的值 二.可变 ...
- golang学习笔记16 beego orm 数据库操作
golang学习笔记16 beego orm 数据库操作 beego ORM 是一个强大的 Go 语言 ORM 框架.她的灵感主要来自 Django ORM 和 SQLAlchemy. 目前该框架仍处 ...
- Python学习笔记五:字符串常用操作,字典,三级菜单实例
字符串常用操作 7月19日,7月20日 ,7月22日,7月29日,8月29日,2月29日 首字母大写:a_str.capitalize() 统计字符串个数:a_str.count(“x”) 输出字符, ...
- Java 字符串(二)字符串常用操作
一.连接字符串 1.连接多个字符串 使用“+”运算符可以实现连接多个字符串的功能.“+” 运算符可以连接多个运算符并产生一个 String 对象. 2.连接其他数据类型 字符串与其他基本数据类型进行连 ...
- python学习笔记(二)、字符串操作
该一系列python学习笔记都是根据<Python基础教程(第3版)>内容所记录整理的 1.字符串基本操作 所有标准序列操作(索引.切片.乘法.成员资格检查.长度.最小值和最大值)都适用于 ...
- Golang基础笔记
<基础> Go语言中的3个关键字用于标准的错误处理流程: defer,panic,recover. 定义一个名为f 的匿名函数: Go 不支持继承和重载. Go的goroutine概念:使 ...
- golang基础之二-基本数据类型和操作符
文件名&关键字&标识符 所有go源码都是以.go结尾 标识符以字母或下划线开头,大小写敏感 下划线_是特殊标识符,用户忽略结果 保留关键字 导入包时可以设置别名 下面是保留关键字: b ...
- Python基础笔记(二)
1. List和Tuple List和Tuple是Python的内置的数据类型,区别在于可变和不可变,List用[]表示,Tuple用()表示,它们之间可以相互转换: # List to Tuple ...
- python3笔记二十:时间操作time
一:学习内容 time时间戳 time元组 time字符串 time时间转换图解 二:time 需要引入:import time 1.概念 UTC(世界协调时间):格林尼治天文时间,世界标准时间,在中 ...
- jQuery学习笔记(二)jQuery中DOM操作
目录 DOM操作分类 jQuery中的各种DOM操作 查找节点 创建节点 删除节点 复制节点 替换节点 包裹节点 属性操作 样式操作 对HTML.文本和值的操作 遍历节点 CSS-DOM操作 小结 本 ...
随机推荐
- Linux系统挂载未分配硬盘空间
先查看未挂载之前的磁盘使用情况 发现磁盘使用率已经达到了96%,迫切需要扩容 查看分区情况fdisk –l 首先确保有可分配的磁盘空间 发现/dev/vda下有400多个G 的空间 所以将/dev/v ...
- 容器一直处于Create状态
通过命令排查 docker inspect b5be1d9e71de报错 "Error": "Could not attach to network fabric-tbc ...
- 集合体系介绍、collection的使用--java进阶day09
1.集合体系结构 我们要学习的集合大体分为两种,一种是单列集合,一种是双列集合 2.单列集合 单列集合又分为两个派系,分别为list接口和set接口,这两个接口皆是collection接口的子接口 3 ...
- 【电脑】VirtualBox 安装 Win98 写网页
VirtualBox 安装 Win98 写网页 记录一下,我成功在VirtualBox中安装了Win98系统,并且安装了Dreamweaver 3.0写网页. 零.起因 学校机房的极域电子教室软件不太 ...
- 我要成为node_modules大师!(一):包管理器选择,依赖关系分析
好家伙 1.npm曾经的一些问题 1. 依赖地狱(Dependency Hell) 嵌套依赖结构:早期版本的 npm 采用嵌套的 node_modules 结构,依赖层级极深,容易导致路径过长问题(尤 ...
- WgelCTF打靶笔记(2)
参考视频:https://www.bilibili.com/video/BV1itwgeHEEk/?spm_id_from=333.1387.upload.video_card.click&v ...
- 3.4K star!全能PDF处理神器开源!文档转换/OCR识别一键搞定
嗨,大家好,我是小华同学,关注我们获得"最新.最全.最优质"开源项目和高效工作学习方法 PDF-Guru 是一款开箱即用的全能型PDF处理工具,支持跨平台文档转换.智能OCR识别. ...
- 工具 | ysoSimple
0x00 简介 ysoSimple是一款简易的Java漏洞利用工具,集成Java反序列化,Hessian反序列化,XStream反序列化,SnakeYaml反序列化,Shiro550,JSF反序列化, ...
- 【HUST】网络攻防实践|TCP会话劫持+序列号攻击netcat对话
文章目录 一.前言 1. 实验环境 2. 攻击对象 3. 攻击目的 4. 最终效果 docker的使用 新建docker docker常用指令 二.正式开始 过程记录 1. ARP欺骗 2. 篡改数据 ...
- Nacos源码—4.Nacos集群高可用分析二
大纲 6.CAP原则与Raft协议 7.Nacos实现的Raft协议是如何写入数据的 8.Nacos实现的Raft协议是如何选举Leader节点的 9.Nacos实现的Raft协议是如何同步数据的 1 ...