golang笔记——string

  任何语言中,字符串操作API都是非常重要的,有些还是熟记比较好,当然如果记不住可以去看源码文件,不得不说GO语言源码看起来非常舒服。

  可以使用反引号代替双引号,来表示原生的字符串,即不进行转义,尤其适合用于表示正则表达式、路径字符串、JSON串。

  每个Unicode码点都使用同样的大小32bit来表示。这种方式比较简单统一,但是它会浪费很多存储空间,因为大数据计算机可读的文本是ASCII字符,本来每个ASCII字符只需要8bit或1字节就能表示。而且即使是常用的字符也远少于65,536个,也就是说用16bit编码方式就能表达常用字符。

  UTF8是一个将Unicode码点编码为字节序列的变长编码。UTF8编码由Go语言之父Ken Thompson和Rob Pike共同发明的,现在已经是Unicode的标准。UTF8编码使用1到4个字节来表示每个Unicode码点,ASCII部分字符只使用1个字节,常用字符部分使用2或3个字节表示。每个符号编码后第一个字节的高端bit位用于表示总共有多少编码个字节。如果第一个字节的高端bit为0,则表示对应7bit的ASCII字符,ASCII字符每个字符依然是一个字节,和传统的ASCII编码兼容。如果第一个字节的高端bit是110,则说明需要2个字节;后续的每个高端bit都以10开头。更大的Unicode码点也是采用类似的策略处理。 

许多类型都会定义一个String方法,因为当使用fmt包的打印方法时,将会优先使用该类型对应的String方法返回的结果打印

  go语言默认使用UTF-8编码,对Unicode的支持非常好。其它语言中一般都提供获取字符串长度的函数,但实际上是获取字节个数,但获取 Unicode 码点个数就可能有些麻烦,比如注册帐号时,无视中英文限制长度时,就要获取Unicode码点个数。GO语言内置了方法:

import "unicode/utf8"

s := "Hello, 世界"
fmt.Println(len(s))                    // "13"
fmt.Println(utf8.RuneCountInString(s)) // "9"

  而遍历输出这些字符是这样的:

for i := 0; i < len(s); {
    r, size := utf8.DecodeRuneInString(s[i:])
    fmt.Printf("%d	%c
", i, r)
    i += size
}

每一次调用DecodeRuneInString函数都返回一个r和长度,r对应字符本身,长度对应r采用UTF8编码后的编码字节数目。实际上,Go语言的range循环在处理字符串的时候,会自动隐式解码UTF8字符串。

for i, r := range "Hello, 世界" {
    fmt.Printf("%d	%q	%d
", i, r, r)
}

string接受到[]rune的类型转换,可以将一个UTF8编码的字符串解码为Unicode字符序列。

如果遇到非法的unicode字符,会解析成 uFFFD,它是一个特殊符号,遇到它就要注意了。

标准库中有四个包对字符串处理尤为重要:bytes、strings、strconv和unicode包。strings包提供了许多如字符串的查询、替换、比较、截断、拆分和合并等功能。

bytes包也提供了很多类似功能的函数,但是针对和字符串有着相同结构的[]byte类型。因为字符串是只读的,因此逐步构建字符串会导致很多分配和复制。在这种情况下,使用bytes.Buffer类型将会更有效,稍后我们将展示。

strconv包提供了布尔型、整型数、浮点数和对应字符串的相互转换,还提供了双引号转义相关的转换。

unicode包提供了IsDigit、IsLetter、IsUpper和IsLower等类似功能,它们用于给字符分类。每个函数有一个单一的rune类型的参数,然后返回一个布尔值。而像ToUpper和ToLower之类的转换函数将用于rune字符的大小写转换。所有的这些函数都是遵循Unicode标准定义的字母、数字等分类规范。strings包也有类似的函数,它们是ToUpper和ToLower,将原始字符串的每个字符都做相应的转换,然后返回新的字符串。

  字节数组 []byte 和 string 可以互相转换,[]byte本质是一个数组(切片?),string是一个常量。bytes包和strings包提供了很多类似的函数,都是为了效率出发,避免转换。bytes包还提供了Buffer类型用于字节slice的缓存。一个Buffer开始是空的,但是随着string、byte或[]byte等类型数据的写入可以动态增长,一个bytes.Buffer变量并不需要处理化,因为零值也是有效的:

当向bytes.Buffer添加任意字符的UTF8编码时,最好使用bytes.Buffer的WriteRune方法,但是WriteByte方法对于写入类似'['和']'等ASCII字符则会更加有效。

  字符串操作相关的API大多封装在 strings 包里,下面列一些常见的

func Count(s, sep string) int

  获取指定子字符串的个数

func Contains(s, substr string) bool

  判断是否包括某子字符串

func ContainsAny(s, chars string) bool

  判断是否包括某字符串中的做任意一个字符,只要包括其中任意一个字符则返回true

func EqualFold(s, t string) bool

  忽略大小写时,判断两个字符串是否相等。

func Fields(s string) []string

  其实就是其它语言中的 Splite 函数,分隔字符串的,这个是按空格分隔。

func Split(s, sep string) []string

  按指定字符分隔字符串

func FieldsFunc(s string, f func(rune) bool) []string

  更强大的自定义分隔字符串,使用函数作为参数

    s := "a,b,c d,e,f"
    slice1 := strings.FieldsFunc(s, func(c rune) bool {
        if c == ',' || c == ' ' {
            return true
        }
        return false
    })
    print_array(slice1)

func HasPrefix(s, prefix string) bool

  判断是否以某字符串开头

func HasSuffix(s, suffix string) bool

  判断是否以某字符串结尾

  

接合这个看源码吧  http://www.widuu.com/archives/01/939.html

原文地址:https://www.cnblogs.com/tianyajuanke/p/5241483.html