前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >区块链开发之Go语言—字符串和字节

区块链开发之Go语言—字符串和字节

作者头像
linxinzhe
发布2018-04-10 15:08:21
1.3K0
发布2018-04-10 15:08:21
举报
文章被收录于专栏:林欣哲

字符串与字节的关系

Go 代码使用 UTF-8 编码,字符串和字节之间的转换依据的是UTF-8编码。注意中文是3个字节对应一个中文的字符串。

下面将归类讲述负责操作字符串和字节的几个标准库

  • strings 包提供了很多操作字符串的简单函数,通常一般的字符串操作需求都可以在这个包中找到。
  • bytes 包提供了对应操作字节的函数。
  • strconv 包提供了基本数据类型和字符串之间的转换。这个包之所以存在,是因为在Go中,没有隐式类型转换。字符串类型和 int、float、bool 等类型之间的转换却没有这么简单。
  • regexp 包提供了正则表达式功能,进行复杂的文本处理
  • unicode 包及其子包 unicode/utf8、unicode/utf16中,提供了对 Unicode 相关编码、解码的支持,同时提供了测试 Unicode 码点(Unicode code points)属性的功能。

strings — 字符串操作

是否存在某个字符或子串

  • funcContains(s,substrstring)bool 完整的substr子串存在于s为true
  • funcContainsAny(s,charsstring)boolchars中的任何一个字符存在于s,则为true
代码语言:javascript
复制
fmt.Println(strings.ContainsAny("in failure", "s g")) //输出  true,因为' '空这个字符存在
  • funcContainsRune(sstring,r rune)boolrune是Go语言里的一个字符的类型,可用来判断
代码语言:javascript
复制
fmt.Println(strings.ContainsRune("你好吗", '你')) // 输出 true ,注意'你'使用单引号

子串出现次数(字符串匹配)

  • funcCount(s,sepstring)int sep在s中出现了几次。

一个特殊的一个例子,可以认为five的每个字符的间隙里都有""

代码语言:javascript
复制
fmt.Println(strings.Count("five", "")) // before & after each rune

字符串分割为[]string

Fields 和 FieldsFunc
代码语言:javascript
复制
func Fields(s string) []string //按空格分割,空格的定义是 unicode.IsSpace
func FieldsFunc(s string, f func(rune) bool) []string //自定义f函数来分割
Split 和 SplitAfter、 SplitN 和 SplitAfterN
代码语言:javascript
复制
func Split(s, sep string) []string { return genSplit(s, sep, 0, -1) }
func SplitAfter(s, sep string) []string { return genSplit(s, sep, len(sep), -1) }
func SplitN(s, sep string, n int) []string { return genSplit(s, sep, 0, n) }
func SplitAfterN(s, sep string, n int) []string { return genSplit(s, sep, len(sep), n) }
  • Split和SplitN的区别:
    • 这里的N表示可以用参数n来决定分成多少份string,剩下的就不分了。所以Split就是尽可能的分,SplitN就是根据你n的要求来分。
  • Split和SplitAfter的区别:
    • 分完的结果里带不带分割符,Split不带分割符,SplitAfter带分割符
代码语言:javascript
复制
fmt.Printf("%q\n", strings.Split("foo,bar,baz", ","))// 输出  ["foo" "bar" "baz"]
fmt.Printf("%q\n", strings.SplitAfter("foo,bar,baz", ","))// 输出 ["foo," "bar," "baz"]
  • 特殊的
代码语言:javascript
复制
fmt.Printf("%q\n", strings.Split(" xyz ", "")) // 输出  [" " "x" "y" "z" " "]

字符串是否有某个前缀或后缀

HasPrefixHasSuffix

代码语言:javascript
复制
// s 中是否以 prefix 开始
func HasPrefix(s, prefix string) bool {
    return len(s) >= len(prefix) && s[0:len(prefix)] == prefix
}
// s 中是否以 suffix 结尾
func HasSuffix(s, suffix string) bool {
    return len(s) >= len(suffix) && s[len(s)-len(suffix):] == suffix
}

字符或子串在字符串中出现的位置

  • funcIndex(s,sepstring)int 在 s 中查找 sep 的第一次出现的位置索引并返回
  • funcIndexFunc(sstring,f func(rune)bool)int Index的自定义版
  • funcIndexAny(s,charsstring)int chars中任何一个Unicode代码点在s中首次出现的位置
  • funcIndexRune(sstring,r rune)int Index的字符版

从后往前找

代码语言:javascript
复制
func LastIndex(s, sep string) int
func LastIndexAny(s, chars string) int
func LastIndexFunc(s string, f func(rune) bool) int

字符串合并的操作

  • funcJoin(a[]string,sepstring)string 将字符串数组(或slice)连接起来可以

字符串重复几次

  • funcRepeat(sstring,countint)string
代码语言:javascript
复制
fmt.Println("ba" + strings.Repeat("na", 2)) // 输出 banana

字符串子串替换

进行字符串替换时,考虑到性能问题,能不用正则尽量别用

  • funcReplace(s,old,newstring,nint)string 用 new 替换 s 中的 old,一共替换 n 个。如果 n < 0,则不限制替换次数,即全部替换
代码语言:javascript
复制
fmt.Println(strings.Replace("oink oink oink", "k", "ky", 2)) // 输出 oinky oinky oink

Replacer 类型

  • funcNewReplacer(oldnew...string)*Replacer 参数 oldnew 是 old-new 对
代码语言:javascript
复制
r := strings.NewReplacer("<", "&lt;", ">", "&gt;") //"<"和"&lt;"是一对,">"和"&gt;"是一对
fmt.Println(r.Replace("This is <b>HTML</b>!")) // 输出 This is &lt;b&gt;HTML&lt;/b&gt;!

Reader 类型

  • 实现了 io 包中的接口。
    • io.Reader(Read 方法)
    • io.ReaderAt(ReadAt 方法)
    • io.Seeker(Seek 方法)
    • io.WriterTo(WriteTo 方法)
    • io.ByteReader(ReadByte 方法)
    • io.ByteScanner(ReadByte 和 UnreadByte 方法)
    • io.RuneReader(ReadRune 方法)
    • io.RuneScanner(ReadRune 和 UnreadRune 方法)
  • funcNewReader(sstring)*Reader 就可以当作一个reader对象在支持io.Reader的接口里使用,比如一个个字节的读取strings.NewReader("abcdefg")

bytes — byte slice 便利操作

因为字符串可以表示为 []byte,因此,bytes 包定义的函数、方法等和 strings 包很类似

是否存在某个子slice

  • funcContains(b,subslice[]byte)bool 子slice subslice 在 b 中,返回 true

[]byte 出现次数

  • funcCount(s,sep[]byte)int slice sep 在 s 中出现的次数(无重叠)

字节数组分割为[]byte

Fields 和 FieldsFunc
代码语言:javascript
复制
func Fields(s []byte) []byte //按空格分割,空格的定义是 unicode.IsSpace
func FieldsFunc(s []byte, f func(rune) bool) []byte //自定义f函数来分割
Split 和 SplitAfter、 SplitN 和 SplitAfterN
代码语言:javascript
复制
func Split(s, sep []byte) []byte { return genSplit(s, sep, 0, -1) }
func SplitAfter(s, sep []byte) []byte { return genSplit(s, sep, len(sep), -1) }
func SplitN(s, sep []byte, n int) []byte { return genSplit(s, sep, 0, n) }
func SplitAfterN(s, sep []byte, n int) []byte { return genSplit(s, sep, len(sep), n) }

字节数组是否有某个前缀或后缀

HasPrefixHasSuffix

字节数组或子字节数组在字节数组中出现的位置

  • funcIndex(s,sep[]byte)int
  • funcIndexFunc(s[]byte,f func(r rune)bool)int Index的自定义版
  • funcIndexAny(s[]byte,charsstring)int
  • funcIndexRune(s[]byte,r rune)int Index的字符版

从后往前找

代码语言:javascript
复制
func LastIndex(s, sep []byte) int
func LastIndexAny(s []byte, chars string) int
func LastIndexFunc(s []byte, f func(rune) bool) int

字节数组合并的操作

  • funcJoin(s[][]byte,sep[]byte)[]byte 将字节数组(或slice)连接起来可以

字节数组重复几次

  • funcRepeat(b[]byte,countint)[]byte

字节数组子串替换

  • funcReplace(s,old,new[]byte,nint)[]byte 用 new 替换 s 中的 old,一共替换 n 个。如果 n < 0,则不限制替换次数,即全部替换

Reader 类型

  • 实现了 io 包中的接口。
    • io.Reader(Read 方法)
    • io.ReaderAt(ReadAt 方法)
    • io.Seeker(Seek 方法)
    • io.WriterTo(WriteTo 方法)
    • io.ByteReader(ReadByte 方法)
    • io.ByteScanner(ReadByte 和 UnreadByte 方法)
    • io.RuneReader(ReadRune 方法)
    • io.RuneScanner(ReadRune 和 UnreadRune 方法)
  • funcNewReader(b[]byte)*Reader

strconv — 字符串和基本数据类型之间转换

  • 基本数据类型包括:
    • 布尔
    • 整型(包括有/无符号、二进制、八进制、十进制和十六进制)
    • 浮点型等。

strconv 包转换错误处理

由于将字符串转为其他数据类型可能会出错,strconv 中的错误处理。

  • 定义了两个 error 类型的变量:
    • ErrRange:值超过了类型能表示的最大范围,比如将 "128" 转为 int8 就会返回这个错误
    • ErrSyntax:语法错误,比如将 "" 转为 int 类型会返回这个错误

字符串和整型之间的转换

  • funcParseInt(sstring,baseint,bitSizeint)(i int64,err error)
    • 如果 base 的值为 0,则会根据字符串的前缀来确定 base 的值:"0x" 表示 16 进制; "0" 表示 8 进制;否则就是 10 进制。
    • base 按给定的进制进行解释。base 的取值为 2~36。
    • bitSize 表示的是整数取值范围,或者说整数的具体类型。取值 0、8、16、32 和 64 分别代表 int、int8、int16、int32 和 int64。当 bitSize==0 时的情况,根据系统32位还是64位决定。
    • -
  • funcParseUint(sstring,baseint,bitSizeint)(n uint64,err error) 转为无符号整型
  • funcAtoi(sstring)(iint,err error) ParseInt便捷版, ParseInt(s,10,0)

整型转为字符串

  • funcFormatUint(i uint64,baseint)string // 无符号整型转字符串
  • funcFormatInt(i int64,baseint)string // 有符号整型转字符串
  • funcItoa(iint)string 相当于 FormatInt(i,10)

字符串和布尔值之间的转换

代码语言:javascript
复制
// 接受 1, t, T, TRUE, true, True, 0, f, F, FALSE, false, False 等字符串;
// 其他形式的字符串会返回错误
func ParseBool(str string) (value bool, err error)
// 直接返回 "true" 或 "false"
func FormatBool(b bool) string
// 将 "true" 或 "false" append 到 dst 中
// 这里用了一个 append 函数对于字符串的特殊形式:append(dst, "true"...)
func AppendBool(dst []byte, b bool)

字符串和浮点数之间的转换

代码语言:javascript
复制
func ParseFloat(s string, bitSize int) (f float64, err error)
func FormatFloat(f float64, fmt byte, prec, bitSize int) string
func AppendFloat(dst []byte, f float64, fmt byte, prec int, bitSize int)
  • 参数
    • 对于 'e', 'E' 和 'f',有效数字用于小数点之后的位数
    • 对于 'g' 和 'G',则是所有的有效数字。
    • fmt,和标准库中fmt包下的一致
    • prec 表示有效数字(对 fmt='b' 无效)
    • bitSize,返回值的位数,虽然是float64,但是如果bitSize=32,这个float64可以轻松转成float32而不损失精度
  • 注意:由于浮点数有精度的问题,精度不一样,ParseFloat 和 FormatFloat 可能达不到互逆的效果。
  • 特别地(不区分大小写),+inf/inf,+infinity/infinity,-inf/-infinity 和 nan 通过 ParseFloat 转换分别返回对应的值(在 math 包中定义)。

regexp — 正则表达式

基本用法

代码语言:javascript
复制
r, err := regexp.Compile(`Hello`)

    if err != nil {
        fmt.Printf("There is a problem with your regexp.\n")
        return
    }

    // Will print 'Match'
    if r.MatchString("Hello Regular Expression.") == true {
        fmt.Printf("Match ")
    } else {
        fmt.Printf("No match ")
    }

Compile和MustCompile

  • Compile和MustCompile基本一致
    • Compile无法编译正则表达式时返回错误
    • MustCompile无法编译正则表达式时抛异常

CompilePOSIX 和 MustCompilePOSIX

  • 他们是按照POSIX ERE (extended regular expression)规则编译
  • POSIX正则表达式分为:BRE(Basic Regular Expression)和ERE(Extended Regular Expressions)

FindString和FindAllString

  • func(re*Regexp)FindString(sstring)string
  • func(re*Regexp)FindAllString(sstring,nint)[]string n为-1则尽可能匹配
  • func(re*Regexp)FindStringIndex(sstring)(loc[]int) 查找到的string的slice的左边和右边,s[loc[0]:loc[1]]
代码语言:javascript
复制
fmt.Printf("%v", r.FindStringIndex(s)) // Prints [7 11], the match starts at 7 and end before 11.
  • func(re*Regexp)FindAllStringIndex(sstring,nint)[][]int 多个loc

unicode — Unicode码点、UTF-8/16编码

三个概念

  • Unicode 只是定义了一个字符和一个编码的映射。存储的字节方式却没有制定。
  • UTF-8 是Unicode的如何存储字符的一种字节编码方式。英文占一个字节,中文占三个字节。
  • UTF-16 也是一种字节编码方式。英文占用两个字节,中文占用两个或者四个字节。

涉及三个库

  • unicode 包含基本的字符判断函数。
  • unicode/utf8 主要负责rune和byte之间的转换
  • unicode/utf16 负责rune和uint16数组之间的转换

注意:

  • 在Go语言中,一个rune就代表一个unicode编码,'中',就是一个rune。
  • go语言的所有代码都是UTF8的,所以如果我们在程序中的字符串都是utf8编码的,但是我们的单个字符(单引号扩起来的)却是unicode的。

unicode包

unicode包含了对rune的判断。

代码语言:javascript
复制
func IsControl(r rune) bool  // 是否控制字符
func IsDigit(r rune) bool  // 是否阿拉伯数字字符,即1-9
func IsGraphic(r rune) bool // 是否图形字符
func IsLetter(r rune) bool // 是否字母
func IsLower(r rune) bool // 是否小写字符
func IsMark(r rune) bool // 是否符号字符
func IsNumber(r rune) bool // 是否数字字符,比如罗马数字Ⅷ也是数字字符
func IsOneOf(ranges []*RangeTable, r rune) bool // 是否是RangeTable中的一个
func IsPrint(r rune) bool // 是否可打印字符
func IsPunct(r rune) bool // 是否标点符号
func IsSpace(r rune) bool // 是否空格
func IsSymbol(r rune) bool // 是否符号字符
func IsTitle(r rune) bool // 是否title case
func IsUpper(r rune) bool // 是否大写字符

utf8包

utf8里面的函数就有一些字节和字符的转换。

判断是否符合utf8编码的函数
  • funcValid(p[]byte)bool
  • funcValidRune(r rune)bool
  • funcValidString(sstring)bool
判断rune的长度的函数
  • funcRuneLen(r rune)int
判断字节串或者字符串的rune数
  • funcRuneCount(p[]byte)int
  • funcRuneCountInString(sstring)(nint)
编码和解码rune到byte
  • funcDecodeRune(p[]byte)(r rune,sizeint)
  • funcEncodeRune(p[]byte,r rune)int
utf16包

较少使用

参考

1.[《Go语言标准库》The Golang Standard Library by Example]( https://books.studygolang.com/The-Golang-Standard-Library-by-Example/chapter01/01.0.html)

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-03-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 林欣哲 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 字符串与字节的关系
  • strings — 字符串操作
    • 是否存在某个字符或子串
      • 子串出现次数(字符串匹配)
        • 字符串分割为[]string
          • Fields 和 FieldsFunc
          • Split 和 SplitAfter、 SplitN 和 SplitAfterN
        • 字符串是否有某个前缀或后缀
          • 字符或子串在字符串中出现的位置
            • 字符串合并的操作
              • 字符串重复几次
                • 字符串子串替换
                  • Replacer 类型
                    • Reader 类型
                    • bytes — byte slice 便利操作
                      • 是否存在某个子slice
                        • []byte 出现次数
                          • 字节数组分割为[]byte
                            • Fields 和 FieldsFunc
                            • Split 和 SplitAfter、 SplitN 和 SplitAfterN
                          • 字节数组是否有某个前缀或后缀
                            • 字节数组或子字节数组在字节数组中出现的位置
                              • 字节数组合并的操作
                                • 字节数组重复几次
                                  • 字节数组子串替换
                                    • Reader 类型
                                    • strconv — 字符串和基本数据类型之间转换
                                      • strconv 包转换错误处理
                                        • 字符串和整型之间的转换
                                          • 整型转为字符串
                                            • 字符串和布尔值之间的转换
                                              • 字符串和浮点数之间的转换
                                              • regexp — 正则表达式
                                                • 基本用法
                                                  • Compile和MustCompile
                                                    • CompilePOSIX 和 MustCompilePOSIX
                                                      • FindString和FindAllString
                                                      • unicode — Unicode码点、UTF-8/16编码
                                                        • unicode包
                                                          • utf8包
                                                            • 判断是否符合utf8编码的函数
                                                            • 判断rune的长度的函数
                                                            • 判断字节串或者字符串的rune数
                                                            • 编码和解码rune到byte
                                                            • utf16包
                                                          • 参考
                                                          相关产品与服务
                                                          区块链
                                                          云链聚未来,协同无边界。腾讯云区块链作为中国领先的区块链服务平台和技术提供商,致力于构建技术、数据、价值、产业互联互通的区块链基础设施,引领区块链底层技术及行业应用创新,助力传统产业转型升级,推动实体经济与数字经济深度融合。
                                                          领券
                                                          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档