1. 字符串简介

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

    str := "Hello World! \n Hello Gopher! \n"

    输出:

    Hello World!
    Hello Gopher!
  • 反引号:字符串使用反引号括起来,其中的相关的转义字符不会被替换

    str :=  `Hello World! \n Hello Gopher! \n`

    输出:

    Hello World! \nHello Gopher! \n

双引号中的转义字符被替换,而反引号中原生字符串中的 \n 会被原样输出。

string类型的零值是为长度为零的字符串,即空字符串 ""

Go 语言中的string类型是一种值类型,存储的字符串是不可变的,如果要修改string内容需要将string转换为[]byte[]rune,并且修改后的string内容是重新分配的

可以通过函数len()来获取字符串所占的字节长度

str := "asd"
len(str)

如果需要获得字符,应该这么做:

package mainimport "fmt"func main() {str := "我与春风皆过客,你携秋水揽星河。"for _, char := range str {fmt.Printf("%c", char)}
}

输出:

我与春风皆过客,你携秋水揽星河。

获取字符串中某个字节的地址的行为是非法的,例如:&str[i]

2. 字符串的拼接

  • 直接使用运算符

    str := "Beginning of the string " + "second part of the string"

    由于编译器行尾自动补全分号的缘故,加号 + 必须放在第一行。

    拼接的简写形式 += 也可以用于字符串:

    s := "hel" + "lo, "
    s += "world!"
    fmt.Println(s) // 输出 “hello, world!”

    里面的字符串都是不可变的,每次运算都会产生一个新的字符串,所以会产生很多临时的无用的字符串,不仅没有用,还会给 GC 带来额外的负担,所以性能比较差。

  • fmt.Sprintf()

    str := fmt.Sprintf("%d:%s", 2018, "年")
    fmt.Println(str) // 2018:年

    内部使用 []byte 实现,不像直接运算符这种会产生很多临时的字符串,但是内部的逻辑比较复杂,有很多额外的判断,还用到了 interface,所以性能一般。

  • strings.Join()

    str = strings.Join([]string{"hello", "world"}, ", ")
    fmt.Println(str) // hello, world

    Join会先根据字符串数组的内容,计算出一个拼接之后的长度,然后申请对应大小的内存,一个一个字符串填入,在已有一个数组的情况下,这种效率会很高,但是本来没有,去构造这个数据的代价也不小。

  • bytes.Buffer

    var buffer bytes.Buffer
    buffer.WriteString("hello")
    buffer.WriteString(", ")
    buffer.WriteString("world")fmt.Print(buffer.String()) // hello, world

    这个比较理想,可以当成可变字符使用,对内存的增长也有优化,如果能预估字符串的长度,还可以用 buffer.Grow() 接口来设置 capacity

  • strings.Builder

    var b1 strings.Builder
    b1.WriteString("ABC")
    b1.WriteString("DEF")fmt.Print(b1.String()) // ABCDEF

    strings.Builder 内部通过 slice 来保存和管理内容。slice 内部则是通过一个指针指向实际保存内容的数组。strings.Builder 同样也提供了 Grow() 来支持预定义容量。当我们可以预定义我们需要使用的容量时,strings.Builder 就能避免扩容而创建新的 slice 了。strings.Builder是非线程安全,性能上和 bytes.Buffer 相差无几。

3. 有关 string 的常用处理

标准库中有四个包对字符串处理尤为重要:bytesstringsstrconvunicode 包。

  • strings 包提供了许多如字符串的查询、替换、比较、截断、拆分和合并等功能
  • bytes包也提供了很多类似功能的函数,但是针对和字符串有着相同结构的 []byte 类型。因为字符串是只读的,因此逐步构建字符串会导致很多分配和复制。在这种情况下,使用bytes.Buffer 类型将会更有效
  • strconv 包提供了布尔型、整型数、浮点数和对应字符串的相互转换,还提供了双引号转义相关的转换
  • unicode 包提供了 IsDigitIsLetterIsUpperIsLower 等类似功能,它们用于给字符分类

3.1 strings 包

3.1.1 判断两个 utf-8 编码字符串是否相同

  • func EqualFold(s, t string) bool

unicode 大写、小写、标题三种格式字符视为相同

func main() {str1 := "Golang"str2 := "golang"fmt.Println(strings.EqualFold(str1, str2)) // true
}

3.1.2 判断字符串 str 是否是以 prefix 开头

  • strings.HasPrefix(s string,prefix string) bool
func main() {str := "哈利·波特"prefix := "哈利"res := strings.HasPrefix(str, prefix)fmt.Println(res) // true
}

3.1.3 判断字符串 str 是否是以 suffix 结尾

  • strings.HasSuffix(str string,suffix string) bool
func main() {str := "哈利·波特"prefix := "波特"res := strings.HasSuffix(str, prefix)fmt.Println(res) // true
}

3.1.4 判断 s 在 str 中首次出现的位置,如果没有出现返回 -1

  • strings.Index(str string,s string) int
func main() {str := "哈利·波特"s := "波特"res := strings.Index(str, s)fmt.Println(res) // 8,这是字节的index,不是Unicode字符数组的index
}

3.1.5 判断 s 在 str 中最后一次出现的位置,如果没有出现返回 -1

  • strings.LastIndex(str tring, s string) int
func main() {str := "哈利·波特"s := "·"res := strings.LastIndex(str, s)fmt.Println(res) // 6,这是字节的index,不是Unicode字符数组的index
}

3.1.6 查询非 ASCII 编码的字符在父字符串中的位置

  • func IndexRune(s string, r rune) int
func main() {str := "哈利·波特"s := '波'res := strings.IndexRune(str, s)fmt.Println(res) // 8,这是字节的index,不是Unicode字符数组的index
}

虽然搜索的时rune字符,但是返回的还是字节的索引。

3.1.7 字符串替换

  • strings.Replace(str string, old string, newStr string, n int) string

str中的 old 字符串替换为 newStr 字符串,返回替换后的结果,n 参数为替换次数,n<0 表示无限次。

func main() {str := "I love her, her name is red"old := "her"newStr := "him"res := strings.Replace(str, old, newStr,1)fmt.Println(res) // I love him, her name is redres = strings.Replace(str, old, newStr,2)fmt.Println(res) // I love him, him name is redres = strings.Replace(str, old, newStr,-2)fmt.Println(res) // I love him, him name is red
}

3.1.8 返回 str 中 substr 出现的次数

  • strings.Count(str string, substr string) int
func main() {str := "I love her, her name is red"substr := "e"count := strings.Count(str, substr)fmt.Println(count) // 5
}

3.1.9 重复 count 次的 str

  • strings.Repeat(str string, count int) string
func main() {str := "love !"count := 3res := strings.Repeat(str, count)fmt.Println(res) //love!love!love!
}

3.1.10 转换大小写

  • strings.ToLower(str string) string
  • strings.ToUpper(str string) string
func main() {str := "I Love You !"lower := strings.ToLower(str)upper := strings.ToUpper(str)fmt.Println(lower) // i love you !fmt.Println(upper) // I LOVE YOU !
}

3.1.11 去掉收尾空格符

  • strings.TrimSpace(str string) string
func main() {str := "I Love You !      "res := strings.TrimSpace(str)fmt.Println(res) // I Love You !
}

3.1.12 去掉 str 两边的 cut 字符串

  • strings.Trim(str string, cut string) string
func main() {str := "ooI Love You !oo"res := strings.Trim(str, "oo")fmt.Println(res) // I Love You !
}

3.1.13 去掉 str 一边的cut字符串

  • strings.TrimLeft(str string, cut string) string
  • strings.TrimRight(str string, cut string) string

3.1.14 以空格作为分隔符,将 str 分隔成切片

  • strings.Fields(str string) []string
func main() {str := "liu hai zhang"res := strings.Fields(str)fmt.Println(res)for _, x := range res {fmt.Println(x)}
}

输出结果:

[liu hai zhang]
liu
hai
zhang

3.1.15 以 split 作为分隔符,将 str 分隔成切片

  • strings.Split(str string,split string) []string
func main() {str := "liu-hai-zhuang"res := strings.Split(str, "-")fmt.Println(res) // [liu hai zhuang]
}

3.1.16 用 sep 把 slice 中的所有元素连接成字符串

  • strings.Join(slice []string,sep string) string
func main() {slice := []string{"liu", "hai", "zhuang"}res := strings.Join(slice, "-")fmt.Println(res) // liu-hai-zhuang
}

3.1.17 判断字符串 s 是否包含子串 substr

  • func Contains(s, substr string) bool
func main() {var str = "中国,台湾"fmt.Println(strings.Contains(str, "台湾")) //truefmt.Println(strings.Contains(str, "日本")) //false
}

3.1.18 判断字符串 s 是否包含 utf-8 码值 r

  • func ContainsRune(s string, r rune) bool
func main() {var r rune = '中'var str = "中国"fmt.Println(strings.ContainsRune(str, r)) //truefmt.Println(strings.ContainsRune(str, '日')) //false
}

3.1.19 判断字符串 s 是否包含字符串 chars 中的任一字符

  • func ContainsAny(s, chars string) bool
func main() {var s = "我爱你,中国"var chars = "我与春风皆过客"var test  = "日"fmt.Println(strings.ContainsAny(s, chars)) //truefmt.Println(strings.ContainsAny(s, test))  //false
}

3.2 bytes 包

方法类似strings包,不给过是针对[]byte 类型,这里省略,可以参考博客https://www.cnblogs.com/golove/p/3287729.html

3.3 strconv 包

3.3.1 string 转 int

  • func Atoi(s string) (i int, err error)
func main() {numStr := "999"num, err := strconv.Atoi(numStr)if err != nil {fmt.Println("can't convert to int")} else {fmt.Printf("type:%T value:%#v\n", num, num) // type:int value:999}
}

另外还可以用 strconv 包下的:

func ParseInt(s string, base int, bitSize int) (i int64, err error)

func ParseUint(s string, base int, bitSize int) (n uint64, err error)

base 指定进制(2到36),如果 base0,则会从字符串前置判断,”0x”16 进制,”0”8 进制,否则是 10 进制;

bitSize 指定结果必须能无溢出赋值的整数类型,08163264 分别代表 intint8int16int32int64

3.3.2 int 转 string

  • func Itoa(i int) string
func main() {num := 200numStr := strconv.Itoa(num)fmt.Printf("type:%T value:%#v\n", numStr, numStr) // type:string value:"200"
}

3.3.3 string 转 bool

  • func ParseBool(str string) (bool, error)

str 为:1tTTRUEtrueTrue 中的一种时为真值
str 为:0fFFALSEfalseFalse 中的一种时为假值

func main() {fmt.Println(strconv.ParseBool("t"))    // truefmt.Println(strconv.ParseBool("TRUE")) // truefmt.Println(strconv.ParseBool("true")) // truefmt.Println(strconv.ParseBool("True")) // truefmt.Println(strconv.ParseBool("0"))    //falsefmt.Println(strconv.ParseBool("f"))    //false
}

3.3.4 string 转 float

  • func ParseFloat(s string, bitSize int) (f float64, err error)

bitSize3264, 对应系统的位数

func main() {strF := "250.56"str, err := strconv.ParseFloat(strF, 64)if err != nil {fmt.Println(err)}fmt.Printf("type:%T value:%#v\n", str, str) // type:float64 value:250.56
}

3.3.5 float 转 string

  • func FormatFloat(f float64, fmt byte, prec, bitSize int) string

bitSize 表示f的来源类型(32float3264float64),会据此进行舍入。

fmt 表示格式:'f'-ddd.dddd)、'b'-ddddp±ddd,指数为二进制)、'e'-d.dddde±dd,十进制指数)、'E'-d.ddddE±dd,十进制指数)、'g'(指数很大时用 'e' 格式,否则 'f' 格式)、'G'(指数很大时用 'E' 格式,否则 'f' 格式)。

prec 控制精度(排除指数部分):对 'f''e''E',它表示小数点后的数字个数;对 'g''G',它控制总的数字个数。如果 prec-1,则代表使用最少数量的、但又必需的数字来表示 f

func main() {num := 250.56str := strconv.FormatFloat(num, 'f', 4, 64)fmt.Printf("type:%T value:%#v\n", str, str) // type:string value:"250.5600"
}

当然,以上类型转string的话,可以直接用fmt.Sprintf实现。

3.4 unicode 包

3.4.1 判断字符大小写

  • func IsUpper(r rune) bool
  • func IsLower(r rune) bool

3.4.2 转换字符大小写

  • func ToUpper(r rune) rune
  • func ToLower(r rune) rune

3.4.3 判断字符 Title 格式

// 判断字符 r 是否为 Unicode 规定的 Title 字符
// 大部分字符的 Title 格式就是其大写格式
// 只有少数字符的 Title 格式是特殊字符
// 这里判断的就是特殊字符
func IsTitle(r rune) bool

3.4.4 字符转换 Title 格式

  • func ToTitle(r rune) rune

3.4.5 将字符转换为指定格式

  • func To(_case int, r rune) rune

_case 取值:UpperCaseLowerCaseTitleCase

3.4.6 判断字符是否是汉字

func main() {for _, r := range "Hello 世界!" {// 判断字符是否为汉字if unicode.Is(unicode.Scripts["Han"], r) {fmt.Printf("%c", r) // 世界}}
}

更多 unicode.Scripts 取值请参考:http://www.cnblogs.com/golove/p/3269099.html

3.4.7 字符判断

  • func IsDigit(r rune) bool

    IsDigit 判断 r 是否为一个十进制的数字字符

  • func IsNumber(r rune) bool

    IsNumber 判断 r 是否为一个数字字符 (类别 N)

  • func IsLetter(r rune) bool

    IsLetter 判断 r 是否为一个字母字符 (类别 L),汉字也是一个字母字符

  • func IsSpace(r rune) bool

    IsSpace 判断 r 是否为一个空白字符,包括\t, \n, \v, \f, \r

  • func IsControl(r rune) bool

    IsControl 判断 r 是否为一个控制字符

  • func IsGraphic(r rune) bool

    IsGraphic 判断字符 r 是否为一个“图形字符”,包括字母标记数字标点符号空格

  • func IsPrint(r rune) bool

    IsPrint 判断字符r是否为 Go 所定义的“可打印字符”,包括字母标记数字标点符号ASCII 空格

  • func IsPunct(r rune) bool

    IsPunct 判断 r 是否为一个标点字符

  • func IsSymbol(r rune) bool

    IsSymbol 判断 r 是否为一个符号字符

『GoLang』string及其相关操作相关推荐

  1. 『Golang』Martini框架入门

    本文介绍golang中的优秀web开发框架martini! 序 Martini框架是使用Go语言作为开发语言的一个强力的快速构建模块化web应用与服务的开发框架.Martini是一个专门用来处理Web ...

  2. 一:redis 的string类型 - 相关操作

    *redisclient使用: =============一类:string的方法================介绍:string是redis的最简单类型,一个key相应一个value,string ...

  3. Lua string字符串相关操作

    前言 字符串操作是 区分大小写的 一.字符串赋值 "" or '' 双引号或单引号 都表字符串 string1 = "a" string2 = 'b' prin ...

  4. 『GoLang』协程与通道

    作为一门 21 世纪的语言,Go 原生支持应用之间的通信(网络,客户端和服务端,分布式计算)和程序的并发.程序可以在不同的处理器和计算机上同时执行不同的代码段.Go 语言为构建并发程序的基本代码块是 ...

  5. 『C++』string类模拟实现

    深拷贝与浅拷贝 首先来看一段代码 #include <iostream> #include <string.h> #include <assert.h>class ...

  6. python 动漫卡通人物图片大全,『TensorFlow』DCGAN生成动漫人物头像_下

    一.计算图效果以及实际代码实现 计算图效果 实际模型实现 相关介绍移步我的github项目. 二.生成器与判别器设计 生成器 相关参量, 噪声向量z维度:100 标签向量y维度:10(如果有的话) 生 ...

  7. 算法中的『前缀和』及『差分』思想详解

    一.基本原理以及实现 1. 一维前缀和 一维前缀和的定义:对于一个从下标从『1』开始的长度为『nnn』的一维数组 『a1,a2,a3,...,ana_1,a_2,a_3,...,a_na1​,a2​, ...

  8. Java String类的相关操作

    Java String类的相关操作 一.如何遍历字符串 //法一 String str="hello world"; for(int i=0;i<str.length();i ...

  9. Python 标准库之 shutil 高阶文件操作『详细』

    Python标准库之 shutil 高阶文件操作『详细』 文章目录 Python标准库之 shutil 高阶文件操作『详细』 一.Python shutil介绍

最新文章

  1. #HTTP协议学习# (七)代理
  2. Latex 数学符号表
  3. Paxos第三篇 - Paxos成员组变更
  4. java定义json数组_Java面试题:json该如何定义?json与xml的区别有哪些?
  5. [转载] python中异常处理的四个句子_Python学习笔记总结(四)异常处理
  6. rk3399_secureboot在linux环境中操作说明
  7. 广州uc优视java面试_UC优视(UC浏览器)面试经验
  8. 关于Movie Studio插入素材格式问题
  9. java 任意 符号_哪种符号表示表面可用任意方法获得?()
  10. net share列出了Windows的默认共享(包括C盘)
  11. npm ERR! could not determine executable to run
  12. 荣耀畅玩7c能用鸿蒙吗,荣耀畅玩7C评测:人脸识别双摄 超高性价比
  13. 用友U9 BP不执行
  14. mysql日期函数之DATEDIFF() if()用法 case when用法
  15. 深度linux时间.年日调整,deepin深度商店中的Linux版应用体验分享(一)
  16. 纯JAVA实现雷电飞机大战<可本地联机>
  17. 前端项目 - 博客系统(纯页面)
  18. 如何在局域网内进行内部访问网站?
  19. 自然语言处理——词性标注、词干提取、词形还原
  20. platform设备驱动简介

热门文章

  1. 王道——数据结构——图(1)
  2. ChatGPT 的情感智能:机器人是否能够感受到情绪?
  3. 禅道-软件测试缺陷管理工具
  4. 安卓开发中,release安装包安装后,打开app后再按home键,再次点击程序图标app再次重新启动的解决办法
  5. 终于给小学生铁粉说清AI教杨超越姐姐跳舞的秘决了
  6. 移动“5G资费”曝光,看完价格,网友直呼:这次太良心了!
  7. 多目标蚂蚁狮子优化算法(Matlab代码实现)
  8. linux学习——硬盘分区和格式化篇
  9. java毕业设计动漫网站Mybatis+系统+数据库+调试部署
  10. css td文字不换行,html td nowrap不换行属性使用方法