Golang學習 - unicode 包

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

const (
	MaxRune         = '\U0010FFFF' // Unicode 碼點的最大值
	ReplacementChar = '\uFFFD'     // 表示無效的碼點
	MaxASCII        = '\u007F'     // 最大 ASCII 值
	MaxLatin1       = '\u00FF'     // 最大 Latin-1 值
)

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

// 判斷字符 r 是否在 rangtab 範圍內。
// 可用的 RangeTable 參見 go/src/unicode/tables.go。
func Is(rangeTab *RangeTable, r rune) bool

// RangeTable 定義一個 Unicode 碼點集合,包含 16 位和 32 位兩個範圍列表。
// 這兩個列表必須通過排序並且不能重疊。R32 中只能包含大於 16 位的值。
type RangeTable struct {
	R16         []Range16
	R32         []Range32
	LatinOffset int // R16 中 Hi <= MaxLatin1 的條目數。
}

// Range16 表示一個 16 位的 Unicode 碼點範圍。範圍從 Lo 到 Hi,具備指定的步長。
type Range16 struct {
	Lo     uint16
	Hi     uint16
	Stride uint16 // 步長
}

// Range32 表示一個 32 位的 Unicode 碼點範圍。範圍從 Lo 到 Hi,具備指定的步長。
// Lo 和 Hi 必須都大於 16 位。
type Range32 struct {
	Lo     uint32
	Hi     uint32
	Stride uint32 // 步長
}

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

// 判斷字符 r 是否爲大寫格式
func IsUpper(r rune) bool

// 判斷字符 r 是否爲小寫格式
func IsLower(r rune) bool

// 判斷字符 r 是否爲 Unicode 規定的 Title 字符
// 大部分字符的 Title 格式就是其大寫格式
// 只有少數字符的 Title 格式是特殊字符
// 這裏判斷的就是特殊字符
func IsTitle(r rune) bool

// ToUpper 將字符 r 轉換爲大寫格式
func ToUpper(r rune) rune

// ToLower 將字符 r 轉換爲小寫格式
func ToLower(r rune) rune

// ToTitle 將字符 r 轉換爲 Title 格式
// 大部分字符的 Title 格式就是其大寫格式
// 只有少數字符的 Title 格式是特殊字符
func ToTitle(r rune) rune

// To 將字符 r 轉換爲指定的格式
// _case 取值:UpperCase、LowerCase、TitleCase
func To(_case int, r rune) rune

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

// 示例:判斷漢字
func main() {
	for _, r := range "Hello 世界!" {
		// 判斷字符是否爲漢字
		if unicode.Is(unicode.Scripts["Han"], r) {
			fmt.Printf("%c", r) // 世界
		}
	}
}

// 更多 unicode.Scripts 取值請參考:http://www.cnblogs.com/golove/p/3269099.html

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

// 示例:判斷大小寫
func main() {
	for _, r := range "Hello ABC!" {
		// 判斷字符是否爲大寫
		if unicode.IsUpper(r) {
			fmt.Printf("%c", r) // HABC
		}
	}
	for _, r := range "Hello abc!" {
		// 判斷字符是否爲小寫
		if unicode.IsLower(r) {
			fmt.Printf("%c", r) // elloabc
		}
	}
	for _, r := range "Hello ᾏᾟᾯ!" {
		// 判斷字符是否爲標題
		if unicode.IsTitle(r) {
			fmt.Printf("%c", r) // ᾏᾟᾯ
		}
	}
}

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

// 示例:輸出 Unicode 規定的標題字符
func main() {
	for _, cr := range unicode.Lt.R16 {
		for i := cr.Lo; i <= cr.Hi; i += cr.Stride {
			fmt.Printf("%c", i)
		}
	} // DžLjNjDzᾈᾉᾊᾋᾌᾍᾎᾏᾘᾙᾚᾛᾜᾝᾞᾟᾨᾩᾪᾫᾬᾭᾮᾯᾼῌῼ
}

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

// 示例:轉換大小寫
func main() {
	s := "Hello 世界!"

	for _, r := range s {
		fmt.Printf("%c", unicode.ToUpper(r))
	} // HELLO 世界!
	for _, r := range s {
		fmt.Printf("%c", unicode.ToLower(r))
	} // hello 世界!
	for _, r := range s {
		fmt.Printf("%c", unicode.ToTitle(r))
	} // HELLO 世界!

	for _, r := range s {
		fmt.Printf("%c", unicode.To(unicode.UpperCase, r))
	} // HELLO 世界!
	for _, r := range s {
		fmt.Printf("%c", unicode.To(unicode.LowerCase, r))
	} // hello 世界!
	for _, r := range s {
		fmt.Printf("%c", unicode.To(unicode.TitleCase, r))
	} // HELLO 世界!
}

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

// ToUpper 將 r 轉換爲大寫格式
// 優先使用指定的映射表 special
// 可用的 SpecialCase 參見 go/src/unicode/casetables.go。
func (special SpecialCase) ToUpper(r rune) rune

// ToLower 將 r 轉換爲小寫格式
// 優先使用指定的映射表 special
func (special SpecialCase) ToLower(r rune) rune

// ToTitle 將 r 轉換爲 Title 格式
// 優先使用指定的映射表 special
func (special SpecialCase) ToTitle(r rune) rune

// SpecialCase 表示特定語言的大小寫映射,好比土耳其語。
// SpecialCase 的方法能夠自定義標準映射(經過重寫)。
type SpecialCase []CaseRange

// CaseRange 表示一個簡單的 Unicode 碼點範圍,用於大小寫轉換。
// 在 Lo 和 Hi 範圍內的碼點,若是要轉換成大寫,只須要加上 d[0] 便可
// 若是要轉換爲小寫,只須要加上 d[1] 便可,若是要轉換爲 Title 格式,
// 只須要加上 d[2] 便可。
type CaseRange struct {
	Lo    uint32
	Hi    uint32
	Delta d // [3]rune
}

// CaseRanges 中 Delta 數組的索引。
const (
	UpperCase = iota
	LowerCase
	TitleCase
	MaxCase
)

// 若是一個 CaseRange 中的 Delta 元素是 UpperLower,則表示這個 CaseRange 是
// 一個有着連續的大寫小寫大寫小寫的範圍。也就是說,Lo 是大寫,Lo+1 是小寫,
// Lo+2 是大寫,Lo+3 是小寫 ... 一直到 Hi 爲止。
const (
	UpperLower = MaxRune + 1 // 不是一個有效的 Delta 元素
)

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

// 示例
func main() {
	s := "Hello 世界!"
	for _, r := range s {
		fmt.Printf("%c", unicode.SpecialCase(unicode.CaseRanges).ToUpper(r))
	} // HELLO 世界!
	for _, r := range s {
		fmt.Printf("%c", unicode.SpecialCase(unicode.CaseRanges).ToLower(r))
	} // hello 世界!
	for _, r := range s {
		fmt.Printf("%c", unicode.SpecialCase(unicode.CaseRanges).ToTitle(r))
	} // HELLO 世界!
}

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

// SimpleFold 在 Unicode 字符表中從字符 r 開始環繞查找(到尾部後再從頭開始)
// 下一個與 r 大小寫相匹配的字符(一個字符的大寫、小寫、標題三者視爲大小寫相
// 匹配),這個函數遵循 Unicode 定義的大小寫環繞匹配表。
//
// 例如:
// SimpleFold('A') = 'a'
// SimpleFold('a') = 'A'
//
// SimpleFold('K') = 'k'
// SimpleFold('k') = 'K' (開爾文符號)
// SimpleFold('K') = 'K'
//
// SimpleFold('1') = '1'
func SimpleFold(r rune) rune

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

// 示例:SimpleFold
func main() {
	s := "ΦφϕkKK"
	// 看看 s 裏面是什麼
	for _, c := range s {
		fmt.Printf("%x  ", c)
	}
	fmt.Println()
	// 大寫,小寫,標題 | 當前字符 -> 下一個匹配字符
	for _, v := range s {
		fmt.Printf("%c, %c, %c | %c -> %c\n",
			unicode.ToUpper(v),
			unicode.ToLower(v),
			unicode.ToTitle(v),
			v,
			unicode.SimpleFold(v),
		)
	}
}

// 輸出結果:
// 3a6  3c6  3d5  6b  4b  212a
// Φ, φ, Φ | Φ -> φ
// Φ, φ, Φ | φ -> ϕ
// Φ, ϕ, Φ | ϕ -> Φ
// K, k, K | k -> K
// K, k, K | K -> k
// K, k, K | K -> K

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

// IsDigit 判斷 r 是否爲一個十進制的數字字符
func IsDigit(r rune) bool

// IsNumber 判斷 r 是否爲一個數字字符 (類別 N)
func IsNumber(r rune) bool

// IsLetter 判斷 r 是否爲一個字母字符 (類別 L)
// 漢字也是一個字母字符
func IsLetter(r rune) bool

// IsSpace 判斷 r 是否爲一個空白字符
// 在 Latin-1 字符集中,空白字符爲:\t, \n, \v, \f, \r,
// 空格, U+0085 (NEL), U+00A0 (NBSP)
// 其它空白字符的定義有「類別 Z」和「Pattern_White_Space 屬性」
func IsSpace(r rune) bool

// IsControl 判斷 r 是否爲一個控制字符
// Unicode 類別 C 包含更多字符,好比代理字符
// 使用 Is(C, r) 來測試它們
func IsControl(r rune) bool

// IsGraphic 判斷字符 r 是否爲一個「圖形字符」
// 「圖形字符」包括字母、標記、數字、標點、符號、空格
// 他們分別對應於 L、M、N、P、S、Zs 類別
// 這些類別是 RangeTable 類型,存儲了相應類別的字符範圍
func IsGraphic(r rune) bool

// IsPrint 判斷字符 r 是否爲 Go 所定義的「可打印字符」
// 「可打印字符」包括字母、標記、數字、標點、符號和 ASCII 空格
// 他們分別對應於 L, M, N, P, S 類別和 ASCII 空格
// 「可打印字符」和「圖形字符」基本是相同的,不一樣之處在於
// 「可打印字符」只包含 Zs 類別中的 ASCII 空格(U+0020)
func IsPrint(r rune) bool

// IsPunct 判斷 r 是否爲一個標點字符 (類別 P)
func IsPunct(r rune) bool

// IsSymbol 判斷 r 是否爲一個符號字符
func IsSymbol(r rune) bool

// IsMark 判斷 r 是否爲一個 mark 字符 (類別 M)
func IsMark(r rune) bool

// IsOneOf 判斷 r 是否在 set 範圍內
func IsOneOf(set []*RangeTable, r rune) bool

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

// 示例
func main() {
	fmt.Println() // 數字
	for _, r := range "Hello 123123一二三!" {
		if unicode.IsDigit(r) {
			fmt.Printf("%c", r)
		}
	} // 123123

	fmt.Println() // 數字
	for _, r := range "Hello 123123一二三!" {
		if unicode.IsNumber(r) {
			fmt.Printf("%c", r)
		}
	} // 123123

	fmt.Println() // 字母
	for _, r := range "Hello\n\t世界!" {
		if unicode.IsLetter(r) {
			fmt.Printf("%c", r)
		}
	} // Hello世界

	fmt.Println() // 空白
	for _, r := range "Hello \t世 界!\n" {
		if unicode.IsSpace(r) {
			fmt.Printf("%q", r)
		}
	} // ' ''\t''\u3000''\n'

	fmt.Println() // 控制字符
	for _, r := range "Hello\n\t世界!" {
		if unicode.IsControl(r) {
			fmt.Printf("%#q", r)
		}
	} // '\n''\t'

	fmt.Println() // 可打印
	for _, r := range "Hello 世界!\t" {
		if unicode.IsPrint(r) {
			fmt.Printf("%c", r)
		}
	} // Hello世界!

	fmt.Println() // 圖形
	for _, r := range "Hello 世界!\t" {
		if unicode.IsGraphic(r) {
			fmt.Printf("%c", r)
		}
	} // Hello 世界!

	fmt.Println() // 掩碼
	for _, r := range "Hello ៉៊់៌៍!" {
		if unicode.IsMark(r) {
			fmt.Printf("%c", r)
		}
	} // ៉៊់៌៍

	fmt.Println() // 標點
	for _, r := range "Hello 世界!" {
		if unicode.IsPunct(r) {
			fmt.Printf("%c", r)
		}
	} // !

	fmt.Println() // 符號
	for _, r := range "Hello (<世=界>)" {
		if unicode.IsSymbol(r) {
			fmt.Printf("%c", r)
		}
	} // <=>
}

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

// 示例:判斷漢字和標點
func main() {
	// 將 set 設置爲「漢字、標點符號」
	set := []*unicode.RangeTable{unicode.Han, unicode.P}
	for _, r := range "Hello 世界!" {
		if unicode.IsOneOf(set, r) {
			fmt.Printf("%c", r)
		}
	} // 世界!
}

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

// 示例:輸出全部 mark 字符
func main() {
	for _, cr := range unicode.M.R16 {
		Lo, Hi, Stride := rune(cr.Lo), rune(cr.Hi), rune(cr.Stride)
		for i := Lo; i >= Lo && i <= Hi; i += Stride {
			if unicode.IsMark(i) {
				fmt.Printf("%c", i)
			}
		}
	}
}

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


相關文章
相關標籤/搜索