『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.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 的常用处理
标准库中有四个包对字符串处理尤为重要: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) 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, "台湾")) //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) 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
取值: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) 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及其相关操作的更多相关文章
- 『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 ...
随机推荐
- Python 赋值、浅拷贝、深拷贝之间区别
赋值 不会开辟新的内存空间,是对原对象值的引用 当原对象值,改变后,赋值的变量也会随之改变 浅拷贝 只会拷贝最外层的对象,会开辟新的内存空间,和原对象是互相独立的 如果这个对象有嵌套对象的话,浅拷贝只 ...
- SQL 练习27
查询每门课程的平均成绩,结果按平均成绩降序排列,平均成绩相同时,按课程编号升序排列 SELECT cid,AVG(score) 平均成绩 from sc GROUP BY cid ORDER BY A ...
- Django3使用WebSocket实现WebShell
前言 最近工作中需要开发前端操作远程虚拟机的功能,简称WebShell. 基于当前的技术栈为react+django,调研了一会发现大部分的后端实现都是django+channels来实现websoc ...
- jpa中使用Query判断条件查询
jpa中使用Query判断条件查询 @Query(value = " select m.* from mining_area as m " + " where 1 = 1 ...
- 将数组对象相同key的内容合并
function fireDuplicate (arr) { var arr = JSON.parse(JSON.stringify(arr)) var ids = [] arr.forEach(fu ...
- c#反射入门篇(Reflection)——MethodInfo 发现方法的属性
网站:https://www.jianshu.com/p/52dc85668d00 也算记录自己的学习篇=.= 适合入门看 这里简单介绍下MethodInfo和他基本的几个方法 简介 MethodIn ...
- ArcGIS:从DEM数据提取对应点的高程
通过Extract Value to Points从DEM数据中提取所需点的高程. 方法/步骤 将DEM数据文件和一个shapefile点文件(分别命名为"DEM"和"P ...
- linnux安装多台redis
安装: 1.获取redis资源 wget http://download.redis.io/releases/redis-4.0.8.tar.gz 2.解压 tar xzvf redis-4.0.8. ...
- 深入Pulsar Consumer的使用方式&源码分析
原文链接 1.使用前准备 引入依赖: <dependency> <groupId>org.apache.pulsar</groupId> <artifactI ...
- js函数和封装
$就是jquery对象,$()就是jQuery(),在里面可以传参数,作用就是获取元素 js对象与jQuery对象的区别:jQuery对象是一个数组,jQuery对象转为js对象:[0] 取第一个即可 ...