Utf8

unicode/utf8提供了多个非常有用的函数,用于查询和操作string和[]bytes中的utf-8字节。

func DecodeLastRune(p []byte) (r rune, size int)

返回字节数组p中最后一个字符(rune)和字符宽度(包含多少个字节). 如果p为空,则返回(RuneError, 0). 另外,如果编码无效,则返回(RuneError, 1). 两者都不是正确的UTF-8字符.

b := []byte("Hello, 世界")

for len(b) > 0 {
    r, size := utf8.DecodeLastRune(b)
    fmt.Printf("%c %v\n", r, size)

    b = b[:len(b)-size]
}

Output

界 3
世 3
  1
, 1
o 1
l 1
l 1
e 1
H 1

func DecodeLastRuneInString(s string) (r rune, size int)

同上,但字节数组换成了字符串

func DecodeRune(p []byte) (r rune, size int)

返回第一个位置的rune和字节宽度

b := []byte("Hello, 世界")

for len(b) > 0 {
    r, size := utf8.DecodeRune(b)
    fmt.Printf("%c %v\n", r, size)

    b = b[size:]
}

Output

H 1
e 1
l 1
l 1
o 1
, 1
  1
世 3
界 3

func DecodeRuneInString(s string) (r rune, size int)

func EncodeRune(p []byte, r rune) int

EncodeRune将r进行utf-8编码,并获得的字节写入到p中(必须包含足够的大小). 并返回写入的字节大小.

r := '世'
buf := make([]byte, 3)

n := utf8.EncodeRune(buf, r)

fmt.Println(buf) //[228 184 150]
fmt.Println(n) //3

func FullRune(p []byte) bool

FullRune判断p是否以一个完整的UTF-8开始的字符。

buf := []byte{228, 184, 150} // 世
fmt.Println(utf8.FullRune(buf)) //true
fmt.Println(utf8.FullRune(buf[:2])) //false

func FullRuneInString(s string) bool

func RuneCount(p []byte) int

返回p中的字符总数. 无效的或不足的编码则被认为是单个runes(宽度为1字节)

buf := []byte("Hello, 世界")
fmt.Println("bytes =", len(buf)) //13
fmt.Println("runes =", utf8.RuneCount(buf)) //9

func RuneCountInString(s string) (n int)

func RuneLen(r rune) int

返回一个r的字节宽度。 如果不是一个有效的UTF-8的值,则返回-1

fmt.Println(utf8.RuneLen('a')) //1
fmt.Println(utf8.RuneLen('界')) //3

func RuneStart(b byte) bool

判断一个字节是否为utf-8编码的第一个字节(utf8编码的第二和后续的字节前两位都是10)

buf := []byte("a界")
for _, i := range buf {
    fmt.Printf("%b ", i)
    //1100001 11100111 10010101 10001100 
}
fmt.Println()
fmt.Println(utf8.RuneStart(buf[0])) //true
fmt.Println(utf8.RuneStart(buf[1])) //true
fmt.Println(utf8.RuneStart(buf[2])) //false

func Valid(p []byte) bool

字节数组包含的都是有效的utf-8编码

valid := []byte("Hello, 世界")
invalid := []byte{0xff, 0xfe, 0xfd} 

fmt.Println(utf8.Valid(valid)) //true
fmt.Println(utf8.Valid(invalid)) //false

func ValidRune(r rune) bool

r是否为一个有效的utf-8范围内数字

valid := 'a'
invalid := rune(0xfffffff)

fmt.Println(utf8.ValidRune(valid)) //true
fmt.Println(utf8.ValidRune(invalid)) //false

func ValidString(s string) bool

valid := "Hello, 世界"
invalid := string([]byte{0xff, 0xfe, 0xfd})

fmt.Println(utf8.ValidString(valid)) //true
fmt.Println(utf8.ValidString(invalid)) //false