『GoLang』string及其相关操作
- 1. 字符串简介
- 2. 字符串的拼接
- 3. 有关 string 的常用处理
- 3.1 strings 包
- 3.1.1 判断两个 utf-8 编码字符串是否相同
- 3.1.2 判断字符串 str 是否是以 prefix 开头
- 3.1.3 判断字符串 str 是否是以 suffix 结尾
- 3.1.4 判断 s 在 str 中首次出现的位置,如果没有出现返回 -1
- 3.1.5 判断 s 在 str 中最后一次出现的位置,如果没有出现返回 -1
- 3.1.6 查询非 ASCII 编码的字符在父字符串中的位置
- 3.1.7 字符串替换
- 3.1.8 返回 str 中 substr 出现的次数
- 3.1.9 重复 count 次的 str
- 3.1.10 转换大小写
- 3.1.11 去掉收尾空格符
- 3.1.12 去掉 str 两边的 cut 字符串
- 3.1.13 去掉 str 一边的cut字符串
- 3.1.14 以空格作为分隔符,将 str 分隔成切片
- 3.1.15 以 split 作为分隔符,将 str 分隔成切片
- 3.1.16 用 sep 把 slice 中的所有元素连接成字符串
- 3.1.17 判断字符串 s 是否包含子串 substr
- 3.1.18 判断字符串 s 是否包含 utf-8 码值 r
- 3.1.19 判断字符串 s 是否包含字符串 chars 中的任一字符
- 3.2 bytes 包
- 3.3 strconv 包
- 3.4 unicode 包
- 3.1 strings 包
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 main
import "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.Buffervar buffer bytes.Buffer
buffer.WriteString("hello")
buffer.WriteString(", ")
buffer.WriteString("world") fmt.Print(buffer.String()) // hello, world
这个比较理想,可以当成可变字符使用,对内存的增长也有优化,如果能预估字符串的长度,还可以用
buffer.Grow()接口来设置capacitystrings.Buildervar 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 的常用处理
标准库中有四个包对字符串处理尤为重要:bytes、strings、strconv 和 unicode 包。
strings包提供了许多如字符串的查询、替换、比较、截断、拆分和合并等功能bytes包也提供了很多类似功能的函数,但是针对和字符串有着相同结构的[]byte类型。因为字符串是只读的,因此逐步构建字符串会导致很多分配和复制。在这种情况下,使用bytes.Buffer类型将会更有效strconv包提供了布尔型、整型数、浮点数和对应字符串的相互转换,还提供了双引号转义相关的转换unicode包提供了IsDigit、IsLetter、IsUpper和IsLower等类似功能,它们用于给字符分类
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 red
res = strings.Replace(str, old, newStr,2)
fmt.Println(res) // I love him, him name is red
res = 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 := 3
res := strings.Repeat(str, count)
fmt.Println(res) //love!love!love!
}
3.1.10 转换大小写
strings.ToLower(str string) stringstrings.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) stringstrings.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, "台湾")) //true
fmt.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)) //true
fmt.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)) //true
fmt.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),如果base为0,则会从字符串前置判断,”0x”是16进制,”0”是8进制,否则是10进制;
bitSize指定结果必须能无溢出赋值的整数类型,0、8、16、32、64分别代表int、int8、int16、int32、int64;
3.3.2 int 转 string
func Itoa(i int) string
func main() {
num := 200
numStr := 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为:1,t,T,TRUE,true,True中的一种时为真值
当str为:0,f,F,FALSE,false,False中的一种时为假值
func main() {
fmt.Println(strconv.ParseBool("t")) // true
fmt.Println(strconv.ParseBool("TRUE")) // true
fmt.Println(strconv.ParseBool("true")) // true
fmt.Println(strconv.ParseBool("True")) // true
fmt.Println(strconv.ParseBool("0")) //false
fmt.Println(strconv.ParseBool("f")) //false
}
3.3.4 string 转 float
func ParseFloat(s string, bitSize int) (f float64, err error)
bitSize:32或64, 对应系统的位数
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的来源类型(32:float32、64:float64),会据此进行舍入。
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.56
str := 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) boolfunc IsLower(r rune) bool
3.4.2 转换字符大小写
func ToUpper(r rune) runefunc 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取值:UpperCase、LowerCase、TitleCase
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) boolIsDigit判断r是否为一个十进制的数字字符func IsNumber(r rune) boolIsNumber判断r是否为一个数字字符 (类别N)func IsLetter(r rune) boolIsLetter判断r是否为一个字母字符 (类别L),汉字也是一个字母字符func IsSpace(r rune) boolIsSpace判断r是否为一个空白字符,包括\t,\n,\v,\f,\rfunc IsControl(r rune) boolIsControl判断r是否为一个控制字符func IsGraphic(r rune) boolIsGraphic判断字符r是否为一个“图形字符”,包括字母、标记、数字、标点、符号、空格func IsPrint(r rune) boolIsPrint判断字符r是否为 Go 所定义的“可打印字符”,包括字母、标记、数字、标点、符号和 ASCII 空格func IsPunct(r rune) boolIsPunct判断r是否为一个标点字符func IsSymbol(r rune) boolIsSymbol判断r是否为一个符号字符
『GoLang』string及其相关操作的更多相关文章
- 『TensorFlow』梯度优化相关
tf.trainable_variables可以得到整个模型中所有trainable=True的Variable,也是自由处理梯度的基础 基础梯度操作方法: tf.gradients 用来计算导数.该 ...
- 『Golang』Martini框架入门
本文介绍golang中的优秀web开发框架martini! 序 Martini框架是使用Go语言作为开发语言的一个强力的快速构建模块化web应用与服务的开发框架.Martini是一个专门用来处理Web ...
- 『Golang』在Golang中使用json
由于要开发一个小型的web应用,而web应用大部分都会使用json作为数据传输的格式,所以有了这篇文章. 包引用 import ( "encoding/json" "gi ...
- 『GoLang』反射
方法和类型的反射 反射是应用程序检查其所拥有的结构,尤其是类型的一种能.每种语言的反射模型都不同,并且有些语言根本不支持反射.Go语言实现了反射,反射机制就是在运行时动态调用对象的方法和属性,即可从运 ...
- 『GoLang』数组与切片
数组 数组是具有相同唯一类型的一组已编号且长度固定的数据项序列(这是一种同构的数据结构):这种类型可以是任意的原始类型例如整型.字符串或者自定义类型. 数组长度必须是一个常量表达式,并且必须是一个非负 ...
- 『GoLang』函数
函数介绍 Go语言函数基本组成包括: 关键字func 函数名 参数列表 返回值 函数体 返回语句 语法如下: func 函数名(参数列表) (返回值列表) { // 函数体 return } 除了ma ...
- 『GoLang』语法基础
标识符 字母或下划线开头 之后只能出现数字.字母.下划线 大小写敏感 Go语言关键字 break default func interface select case defer go map str ...
- 『Golang』MongoDB在Golang中的使用(mgo包)
有关在Golang中使用mho进行MongoDB操作的最简单的例子.
- 一:redis 的string类型 - 相关操作
*redisclient使用: =============一类:string的方法================ 介绍:string是redis的最简单类型,一个key相应一个value,strin ...
随机推荐
- SQL 练习6
查询在 SC 表存在成绩的学生信息 SELECT * from Student WHERE SId in (SELECT SId from SC)
- mysql如何查看是32位还是64位?
mysql如何查看是32位还是64位? 1. mysql -V或mysql --version 或者 2. 进入mysql,输入命令:show variables like '%version_%';
- jpa 指定字段内容按照顺序排序(orderBy when then)
query.orderBy( criteriaBuilder.desc( criteriaBuilder.selectCase() .when(criteriaBuilder.equal(root.g ...
- jpa写原生sql-EntityManager
废话不多说 package com.meeno.trainsys.meeting.service; import com.google.common.collect.Lists; import com ...
- Qt foreach关键字用法(无师自通)
Qt 提供一个关键字 foreach (实际是 <QtGlobal> 里定义的一个宏)用于方便地访问容器里所有数据项. foreach 关键字用于遍历容路中所有的项,使用 foreach ...
- WPF以鼠标当前位置进行缩放
<Window x:Class="ImageViewer.MainWindow" xmlns="http://schemas.microsoft.com/winfx ...
- Qt 中事件与处理
一.事件与处理程序在运算过程中发生的一些事情:鼠标单击.键盘的按下...这些的事件的监控与处理在Qt中不是以信号的方式处理的.当这些事件发生时会调用QObject类中的功能函数(虚函数),所有的控件类 ...
- DNS地址列表
DNS测试工具(DNSBench):https://www.grc.com/dns/benchmark.htm DNS列表收集: Google DNS [URL]https://developers. ...
- Git中使用.gitignore忽略文件的推送
转载自:https://blog.csdn.net/lk142500/article/details/82869018 windows下可以用另存为生成gitignore 文件 1 简介 在使用Git ...
- 基于 Mysql 实现一个简易版搜索引擎
前言 前段时间,因为项目需求,需要根据关键词搜索聊天记录,这不就是一个搜索引擎的功能吗? 于是我第一时间想到的就是 ElasticSearch 分布式搜索引擎,但是由于一些原因,公司的服务器资源比较紧 ...