strings包API
检索字符串
代码案例
package main
import (
"fmt"
"strings"
"unicode"
)
func main() {
stringAPI()
}
func stringAPI() {
var str string = "hello world hello world Go"
//是否包含字符/字符串
contains := strings.Contains(str, "hello")//底层Index(s, substr) >= 0
fmt.Printf("str 包含 hello --- %t \n", contains)
containsAny := strings.ContainsAny(str, "view")// 底层IndexAny(s, chars) >= 0
fmt.Printf("str 包含 view中任一字符--%t \n",containsAny)
var r rune='d'
containsRune := strings.ContainsRune(str, r)
fmt.Printf("str 包含字符d --%t \t",containsRune)
//包含字符的个数
count := strings.Count(str, "hello")
fmt.Printf("str 包含字符串 hello 的个数 %d \n",count)
//前缀与后缀
println(strings.HasPrefix(str, "hello"))//true
println(strings.HasSuffix(str, "hello Go"))//true
//字符串首次出现的位置
println(strings.Index(str, "Go"))//18
//字符串中任一一个unicode码值在字符串中首次出现的位置--即字符串包含sep中任意字符的位置(取数字最小的那个)
println(strings.IndexAny(str, "hc")) //不包含 则返回 -1
str2:= "GFG is the Best"
res2:= strings.IndexAny(str2, "it")//it都包含,但是i的位置靠前,则返回i的位置
println(res2)
//字符串中字节的位置
println(strings.IndexByte(str, 'h'))
println(strings.IndexRune(str, 'w'))
//字符串最后一次出现的位置
println(strings.LastIndex(str, "GG"))
println(strings.LastIndexAny(str, "Go"))
//返回字符串中最后一个最后一个满足func(c)条件的Unicode码点的索引
println("lastIndexFunc--",strings.LastIndexFunc(str, func(r rune) bool {
return r=='w'
}))
//字符串比较
strings.EqualFold(str,str2)//false
str4:="12345"
println(strings.LastIndexFunc(str4, unicode.IsNumber))
}
字符串切割
func cutString() {
str := "hello world hello go"
fields := strings.Fields(str) //返回一个string切片(以空白字符串切割)
for i, i2 := range fields {
fmt.Printf("下标i -- %d \t value-- %s \n", i, i2)
}
fieldsFunc := strings.FieldsFunc(str, func(r rune) bool {
//以字符 o进行切割
return r == 'o'
})
for i, i2 := range fieldsFunc {
fmt.Printf("下标i -- %d \t value-- %s \n", i, i2)
}
str2 := "hello1world2go3hello"
//以数字进行切割
i := strings.FieldsFunc(str2, unicode.IsNumber)
for i, i2 := range i {
fmt.Printf("下标i -- %d \t value-- %s \n", i, i2)
}
//以字符串 l 进行切割 ,最后去掉 l
split := strings.Split(str, "l") //return genSplit(s, sep, 0, -1) "he o wor d he o go"
fmt.Println(split) // [he o wor d he o go]
//以字符串 l 进行切割 ,最后分割处附上l
/*
过程如下 "he o wor d he o go" --> he l o wor d he l o go -->hel l o worl d hel l o go
*/
splitAfter := strings.SplitAfter(str, "l") // "hel l o worl d hel lo go"
fmt.Println("splitAfter--", splitAfter) //[hel l o worl d hel l o go]
str3 := "helloworld"
//以字符串l 进行切割 n表示返回的切片数
splitN := strings.SplitN(str3, "l", 4) // he owor d
fmt.Println("SplitN--", splitN) //[he owor d]
splitAfterN := strings.SplitAfterN(str3, "l", 4)
fmt.Println("SplitAfterN--", splitAfterN) //[hel l oworl d]
//将字符串中单词首字母大写返回 //已被废弃
title := strings.Title(str)
fmt.Println(title) //Hello World Hello Go
//将字符串全部转换成大写
toTitle := strings.ToTitle(str) //返回字符串的副本
fmt.Println("toTitle--", toTitle) //HELLO WORLD HELLO GO
lower := strings.ToLower(str)
println("lower", lower) //转换成小写 hello world hello go
special := strings.ToTitleSpecial(unicode.SpecialCase{}, str)
fmt.Println("special---", special)
println(strings.ToUpper(str)) //换换成大写 HELLO WORLD HELLO GO
}
修剪字符串
func TrimString(){
str:="hello world hello Go"
//将字符串str中首尾包含 "ho"中任一字符 的字符去掉
trim := strings.Trim(str, "ho")
fmt.Println(trim)
//将字符串str中左边包含 "ho"中任一字符 的字符去掉
println(strings.TrimLeft(str, "ho"))
//将字符串str中右边包含 "ho"中任一字符 的字符去掉
println(strings.TrimRight(str, "ho"))
//两边满足f(r)==true的删除
println(strings.TrimFunc(str, func(r rune) bool {
return r == 'o'
}))
strings.TrimLeftFunc(str,unicode.IsSpace)
strings.TrimRightFunc(str,unicode.IsSpace)
//删除两边空格
strings.TrimSpace(str)
//删除前缀字符串"he"
strings.TrimPrefix(str,"he")
//删除后缀字符串 "he"
strings.TrimSuffix(str,"he")
}
字符串比较
// 字符串比较
func compareString() {
str := "hellohello"
str2 := "Hello"
str3 := "hello2"
//比较字符串是否相等 忽略大小写
println(strings.EqualFold(str, str2))
println(strings.EqualFold(str, str3))
//比较字符串大小(按字典顺序) 不忽略大小写
println(strings.Compare(str, str2)) // str>str2
println(strings.Compare(str, str3)) //
//字符串重复 count 次
println(strings.Repeat(str, 2))
//将旧 字符串替换为新的n表示替换的次数
println(strings.Replace(str, "ll", "oo", 1))
str4 := []string{
"Ha", "Eb", "Lc", "Ld", "Of",
}
//拼接字符为字符串
println(strings.Join(str4, "-"))
}
strconv包API
字符串转换数字
//转换时发生的错误暂且不管他
func strconvTest(){
str:="1"
//字符串转换为数字 十进制
atoi, err := strconv.Atoi(str) //返回值为整数和err
if err==nil{
fmt.Printf("%d \n",atoi)
}
//fmt.Println(err)
/*
str 字符串,base 转换的进制, bitSize 转换的证书类型 int int8 int16 int32 int64
*/
//将数字转换相应的进制
parseInt, err := strconv.ParseInt(str, 2, 10)
fmt.Println(parseInt)
floa:="13.14"
//字符串转浮点数 精度由bitSize决定,float32 精度为32,会有损失 float64 精度为64
parseFloat, err := strconv.ParseFloat(floa, 64 )
fmt.Println(parseFloat)
//字符串转换为布尔类型 字符串接收1, t, T, TRUE, true, True, 0, f, F, FALSE, false, False 否则返回false 跟err!=nil
parseBool, err := strconv.ParseBool(str)
fmt.Println(parseBool)
uni:="10"
//转换成无符号
parseUint, err := strconv.ParseUint(uni, 10, 16)
fmt.Println(parseUint)
}
数字转字符串
// 其他类型转换成字符串
func formatStr() {
inte := 100
itoa := strconv.Itoa(int(inte))
fmt.Printf("int转换后的类型--%T 值为%v \n", itoa, itoa)
formatInt := strconv.FormatInt(int64(inte), 2) //返回值字符串
fmt.Printf("int64转换后的类型--%T \t 值为--%v \n", formatInt, formatInt) //string
formatBool := strconv.FormatBool(true)
fmt.Printf("布尔值转换后类型-- %T --值为%v \n", formatBool, formatBool)
formatUint := strconv.FormatUint(uint64(inte), 10)
fmt.Printf("Uint转换后的类型--%T 值为%v \n", formatUint, formatUint)
/*
fmt 转换的格式 f表示 b 表示二进制,e表示十进制E表示十进制指数
*/
ft := strconv.FormatFloat(13.14, 'f', 2, 64)
fmt.Printf("类型---%T 值为%v \n",ft,ft)
}
regexp正则表达式包
正则表达式的特别备注说:
- (1)大写英文字母的正则表达式,除了可以写成[A-Z],还可以写成[\x41-\x5A]。因为在ASCII码字典中A-Z被排在了65~90号(也就是ASCII码的第66位到第91位),换算成十六进制就是0x41-0x5A。
- (2)[0-9],可以写成[\x30-\x39]。
- (3)[a-z],可以写成[\x61-\x7A]。
- (4)中文的正则表达式为:[\u4E00-\u9FA5]。
/*
regexp正则表达式包
由元字符组成的一种字符串匹配的模式,
使用这种模式可以实现对文本内容解析、校验、替换。
模糊查询与批量替换
*/
func regexpTest() {
//匹配字节切片中任一值是否符合正则表达式
match, err := regexp.Match("[0-9]", []byte{'1', '2'})
if err == nil {
fmt.Println(match)
}
//匹配字符串中任意字符匹配正则表达式
matchString, err := regexp.MatchString("[a-z]", "agddas45adhkdah")
fmt.Println(matchString)
//将正则表达式字符串编译成正则表达式对象
compile, err := regexp.Compile("[0-9]")
fmt.Printf("%T --- %v \n", compile, compile)
//将正则表达式字符串编译成正则表达式对象 但是不返回err,会panic
mustCompile := regexp.MustCompile("[a-z]")
fmt.Printf("%T --- %v \n", mustCompile, mustCompile)
b := mustCompile.Match([]byte{'a', '1', 'e'})
fmt.Printf("%T \n", b)
//将符合正则的部分替换成指定内容
text := "若b水c三d千a我e只f取g一瓢h饮"
r := regexp.MustCompile("[a-d]+")
s := string(r.ReplaceAll([]byte(text), []byte("")))
fmt.Printf("%T %v \n",s,s)
r2, err := regexp.Compile("[0-9]")
if err==nil {
//按照正则进行拆分成字符串组成切片,长度超过指定参数,则不在分割
//若没有符合条件的,则就切片中就一个字符串
split := r2.Split(text, 20)
fmt.Println(split)
}
}
*regexp.Regexp
该对象由Compile 跟MustCompile 生成,之后可以根据定义的正则对象去操作字符串
r2, err := regexp.Compile("[a-z]")
if err==nil {
//按照正则进行拆分成字符串组成切片,长度超过指定参数,则不在分割
//若没有符合条件的,则就切片中就一个字符串
split := r2.Split(text, 20)
fmt.Println(split)
}
find := r2.Find([]byte{'a', 'b'}) //最左匹配
fmt.Printf("%T %v\n",find,find)
r2, err := regexp.Compile(`(?m)(?P<key>\w+):\s+(?P<value>\w+)$`)
if err==nil {
//按照正则进行拆分成字符串组成切片,长度超过指定参数,则不在分割
//若没有符合条件的,则就切片中就一个字符串
split := r2.Split(text, 20)
fmt.Println(split)
}
find := r2.Find([]byte{'a', 'b'}) //最左匹配
fmt.Printf("%T %v\n",find,find)
//FindIndex 返回一个双元素整数切片,用于定义
//正则表达式 中最左侧的匹配项
content := []byte(`
# comment line
option1: value1
option2: value2
`)
index := r2.FindIndex(content)
fmt.Println(index)
fmt.Println(string(content[index[0]:index[1]]))
一些关于正则的其他API大家可以自行尝试:
time包API
time包提供了时间的显示和测量用的函数。日历的计算采用的是公历
func TimeTest() {
//返回当前本地时间
now := time.Now()
fmt.Printf("%T , %v \n", now, now)
//Month使用系统代的 time.月份英文名
//月份 +1 为当前的月份
date := time.Date(2023, time.May, 21, 9, 32, 10, 1000, time.Local)
fmt.Printf("%T -- %v \n", date, date)
parse, err := time.Parse("2006-01-02 15:04:05", "2023-05-21 09:40:08")
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("%T ,%v \n", parse, parse)
//如果layout不是"2006-01-02 15:14:05" 则转换会出现 异常情况 0001-01-01 00:00:00 +0000 UTC
t2, _ := time.Parse("2006-01-02 15:04:05", "2023-05-21 09:42:08")
fmt.Println(t2)
t, err := time.Parse("2006-01-02 15:04:05", "2017-12-03 22:01:02")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(t)
//根据时间戳返回时间
unix := time.Unix(567890200, 19000)
fmt.Println(unix) //1987-12-31 03:16:40.000019 +0800 CST
//获得当前时间的月份
month := time.Now().Month()
day := time.Now().Day()
hour := time.Now().Hour()
fmt.Printf("%T %T %T ,%v %v %v \n", month, day, hour, month, day, hour)
sub := time.Now().Sub(time.Now()).Hours()
fmt.Println("交卷啦", sub)
//解析持续时间字符串
duration, _ := time.ParseDuration("5h39m")
fmt.Printf("%T ,%v\n", duration, duration)
//返回 +time后的时间
add := time.Now().Add(duration)
fmt.Printf("%T %v\n", add, add)
//返回+year+month+time后的时间
addDate := time.Now().AddDate(10, 2, 13)
fmt.Printf("%T %v\n", addDate, addDate)
}
layout的值 好像必须为"2006-01-02 15:04:05" ,否则转换就达不到预期,不知是什么情况\
0001-01-01 00:00:00 +0000 UTC
2006-01-02 15:04:05这是Go诞生的日期
math包API
func MathTest() {
//是否不是数字
n := math.IsNaN(3.1415926534564)
fmt.Println(n)
//返回不小于x的最小整数(浮点值)+4.000000e+000
println(math.Ceil(3.124))
//返回不大于x的最小整数(浮点值)
println(math.Floor(-3.1415926)) //-4.000000e+000
//返回整数部分
println("整数部分",math.Trunc(3.245))
println("绝对值",math.Abs(-1234.678))
println("较大值",math.Max(10, 20))
println("较小值",math.Min(10, 20))
dim := math.Dim(100, -239)
println("x-y跟0比较大值:", dim)
float123 := strconv.FormatFloat(dim, 'f', 2, 64)
fmt.Println(float123)
mod := math.Mod(12, 14)
fmt.Println(mod)
fmt.Println(math.Sqrt(4))
fmt.Println(math.Cbrt(27))
//返回 (p^2+q^2 )的平方根
println("这是什么值:",math.Hypot(3, 4))
println(math.Pow(2, 3))
println(math.Sin(1))//求正弦
println(math.Cos(1))//求余弦
println("自然对数",math.Log(100))
println("以2为底的对数",math.Log2(100))
println("以10为底的对数",math.Log10(100))
}
math/rand生成随机数
“math/rand”包实现了伪随机数生成器,能够生成整型和浮点型的随机数。
使用随机数生成器需要放入种子。
可以使用Seed()函数生成一个不确定的种子放入随机数生成器,
这样每次运行随机数生成器都会生成不同的序列。
如果没有在随机数生成器中放入种子,则默认使用具有确定性状态的种子;
//随机数
/**
“math/rand”包实现了伪随机数生成器,能够生成整型和浮点型的随机数。
使用随机数生成器需要放入种子。
可以使用Seed()函数生成一个不确定的种子放入随机数生成器,
这样每次运行随机数生成器都会生成不同的序列。
如果没有在随机数生成器中放入种子,则默认使用具有确定性状态的种子
*/
func randTest() {
//给指定的种子创建一个伪随机资源
source := rand.NewSource(9) //返回值source
fmt.Printf("%T ---- %v \n", source, source)
//New返回一个新的Rand,它使用src中的随机值 生成其他随机值。
r := rand.New(source) //返回值*Rand
fmt.Printf("%T --%v \n", r, &r)
println("随机数1--", rand.Int63())
println("随机数2--", rand.Int63())
//这样总是生成固定的随机数
println("随机数11", r.Int()) //33637761161952934 每次运行结果一样
println("随机数22", r.Int()) //933416481206120304 每次运行结果一样
intn := rand.Intn(100)
fmt.Println("100内的随机数", intn)
//每次生成不一样的source
newSource := rand.NewSource(time.Now().UnixNano())
r2 := rand.New(newSource)
//这里为了跟int64()函数区别,所以用了int63()
fmt.Printf("随机数33---%v \n",r2.Int63())
f := rand.Float64()
fmt.Println(f)
//获取某个范围内的随机值
rand.Seed(time.Now().UnixNano())
i := rand.Intn(101) + 100
fmt.Printf("100-200之间随机数:%v \n",i)
}
键盘输入
func SysIn() {
usname := ""
age := 0
//这里使用地址
//Scanln类似于Scan,但在换行符和处停止扫描
//最后一项后面必须有换行符或EOF。
//scanln, err := fmt.Scanln(usname, age)//这里是直接传的值
scanln, err := fmt.Scanln(&usname, &age)
if err != nil {
println(err) //(0xe0f678,0xc0000502d0)
}
println("接收到的参数个数", scanln) //返回接收到的参数的个数,如果没有接收到,那么参数为默认值
fmt.Println("账号信息:", usname, age)
hobby := ""
grade := 0
scan, err := fmt.Scan(&hobby, &grade)
if err != nil {
fmt.Printf("err---%v\n", err)
}
println("接收到的参数个数", scan) //返回接收到的参数的个数,如果没有接收到,那么参数为默认值
fmt.Println("爱好与年级,", hobby, grade)
//格式化后的输入
var name1 string
var age1 byte
var salary1 float32
var isOffer1 bool
fmt.Println("请输入您的姓名, 年龄,薪水,是否拿到offer")
fmt.Scanf("%s %d %f %t", &name1, &age1, &salary1, &isOffer1)
fmt.Printf("姓名:%v\n 年龄:%v\n 薪水:%v\n 是否拿到offer:%v\n", name1, age1, salary1, isOffer1)
//指定文本
name1 = "弱水三千 100"
sscan, err := fmt.Sscan(name1, &name1, &age1)
fmt.Println(sscan, name1, age1)
}
习题:
(1)将字符串内所有abc替换成xyz,并转换成大写。
func ReplaceR(str string) string {
replace := strings.Replace(str, "abc", "xyz", len(str))
return replace
}
(2)编写一个程序,输入某个日期,输出该日期是星期几
func DayDay() {
days := ""
fmt.Println("请输入一个日期")
scanN, err := fmt.Scan(&days)
if err != nil {
fmt.Println("输入的日期格式不正确")
return
}
fmt.Println("输入的参数个数--", scanN)
parse, err := time.Parse("2006-01-02", days)
location, err := time.ParseInLocation("2006-01-02", days, time.Local)
fmt.Println("location--",location)
fmt.Println("days--",days)
fmt.Println(parse)
weekday := parse.Weekday()
switch weekday {
case time.Sunday:
fmt.Println("周日")
case time.Monday:
fmt.Println("周一")
}
}