Golang學習 - unicode/utf8 包

------------------------------------------------------------

// 編碼所需的基本數字
const (
	RuneError = '\uFFFD'     // 錯誤的 Rune 或 Unicode 代理字符
	RuneSelf  = 0x80         // ASCII 字符範圍
	MaxRune   = '\U0010FFFF' // Unicode 碼點的最大值
	UTFMax    = 4            // 一個字符編碼的最大長度
)

------------------------------------------------------------

// 將 r 轉換爲 UTF-8 編碼寫入 p 中(p 必須足夠長,一般爲 4 個字節)
// 若是 r 是無效的 Unicode 字符,則寫入 RuneError
// 返回寫入的字節數
func EncodeRune(p []byte, r rune) int

// 解碼 p 中的第一個字符,返回解碼後的字符和 p 中被解碼的字節數
// 若是 p 爲空,則返回(RuneError, 0)
// 若是 p 中的編碼無效,則返回(RuneError, 1)
// 無效編碼:UTF-8 編碼不正確(好比長度不夠)、結果超出 Unicode 範圍、編碼不是最短的。
// 關於最短編碼:能夠用四個字節編碼一個單字節字符,但它不是最短的,好比:
// [111100000 10000000 10000000 10111000] 不是最短的,應該使用 [00111000]
func DecodeRune(p []byte) (r rune, size int)

// 功能同上,參數爲字符串
func DecodeRuneInString(s string) (r rune, size int)

// 解碼 p 中的最後一個字符,返回解碼後的字符,和 p 中被解碼的字節數
// 若是 p 爲空,則返回(RuneError, 0)
// 若是 p 中的編碼無效,則返回(RuneError, 1)
func DecodeLastRune(p []byte) (r rune, size int)

// 功能同上,參數爲字符串
func DecodeLastRuneInString(s string) (r rune, size int)

// FullRune 檢測 p 中第一個字符的 UTF-8 編碼是否完整(完整並不表示有效)。
// 一個無效的編碼也被認爲是完整字符,由於它將被轉換爲一個 RuneError 字符。
// 只有「編碼有效但長度不夠」的字符才被認爲是不完整字符。
// 也就是說,只有截去一個有效字符的一個或多個尾部字節,該字符纔算是不完整字符。
// 舉例:
// "好"     是完整字符
// "好"[1:] 是完整字符(首字節無效,可轉換爲 RuneError 字符)
// "好"[2:] 是完整字符(首字節無效,可轉換爲 RuneError 字符)
// "好"[:2] 是不完整字符(編碼有效但長度不夠)
// "好"[:1] 是不完整字符(編碼有效但長度不夠)
func FullRune(p []byte) bool

// 功能同上,參數爲字符串
func FullRuneInString(s string) bool

// 返回 p 中的字符個數
// 錯誤的 UTF8 編碼和長度不足的 UTF8 編碼將被看成單字節的 RuneError 處理
func RuneCount(p []byte) int

// 功能同上,參數爲字符串
func RuneCountInString(s string) (n int)

// RuneLen 返回須要多少字節來編碼字符 r,若是 r 是無效的字符,則返回 -1
func RuneLen(r rune) int

// 判斷 b 是否爲 UTF8 字符的首字節編碼,最高位(bit)是否是 10 的字節就是首字節。
func RuneStart(b byte) bool

// Valid 判斷 p 是否爲完整有效的 UTF8 編碼序列。
func Valid(p []byte) bool

// 功能同上,參數爲字符串
func ValidString(s string) bool

// ValidRune 判斷 r 可否被正確的轉換爲 UTF8 編碼
// 超出 Unicode 範圍的碼點或 UTF-16 代理區中的碼點是不能轉換的
func ValidRune(r rune) bool

------------------------------

// 示例
func main() {
	b := make([]byte, utf8.UTFMax)

	n := utf8.EncodeRune(b, '好')
	fmt.Printf("%v:%v\n", b, n) // [229 165 189 0]:3

	r, n := utf8.DecodeRune(b)
	fmt.Printf("%c:%v\n", r, n) // 好:3

	s := "你們好"
	for i := 0; i < len(s); {
		r, n = utf8.DecodeRuneInString(s[i:])
		fmt.Printf("%c:%v   ", r, n) // 大:3   家:3   好:3
		i += n
	}
	fmt.Println()

	for i := len(s); i > 0; {
		r, n = utf8.DecodeLastRuneInString(s[:i])
		fmt.Printf("%c:%v   ", r, n) // 好:3   家:3   大:3
		i -= n
	}
	fmt.Println()

	b = []byte("好")
	fmt.Printf("%t, ", utf8.FullRune(b))     // true
	fmt.Printf("%t, ", utf8.FullRune(b[1:])) // true
	fmt.Printf("%t, ", utf8.FullRune(b[2:])) // true
	fmt.Printf("%t, ", utf8.FullRune(b[:2])) // false
	fmt.Printf("%t\n", utf8.FullRune(b[:1])) // false

	b = []byte("你們好")
	fmt.Println(utf8.RuneCount(b)) // 3

	fmt.Printf("%d, ", utf8.RuneLen('A'))          // 1
	fmt.Printf("%d, ", utf8.RuneLen('\u03A6'))     // 2
	fmt.Printf("%d, ", utf8.RuneLen('好'))          // 3
	fmt.Printf("%d, ", utf8.RuneLen('\U0010FFFF')) // 4
	fmt.Printf("%d\n", utf8.RuneLen(0x1FFFFFFF))   // -1

	fmt.Printf("%t, ", utf8.RuneStart("好"[0])) // true
	fmt.Printf("%t, ", utf8.RuneStart("好"[1])) // false
	fmt.Printf("%t\n", utf8.RuneStart("好"[2])) // false

	b = []byte("你好")
	fmt.Printf("%t, ", utf8.Valid(b))     // true
	fmt.Printf("%t, ", utf8.Valid(b[1:])) // false
	fmt.Printf("%t, ", utf8.Valid(b[2:])) // false
	fmt.Printf("%t, ", utf8.Valid(b[:2])) // false
	fmt.Printf("%t, ", utf8.Valid(b[:1])) // false
	fmt.Printf("%t\n", utf8.Valid(b[3:])) // true

	fmt.Printf("%t, ", utf8.ValidRune('好'))        // true
	fmt.Printf("%t, ", utf8.ValidRune(0))          // true
	fmt.Printf("%t, ", utf8.ValidRune(0xD800))     // false  代理區字符
	fmt.Printf("%t\n", utf8.ValidRune(0x10FFFFFF)) // false  超出範圍
}

------------------------------------------------------------



相關文章
相關標籤/搜索