------------------------------------------------------------ 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) } } } } ------------------------------------------------------------