1 概述
Go语言的字符串是使用 UTF-8 编码的。UTF-8 是 Unicode 的实现方式之一。本文内容包括:UTF-8 和 Unicode 的关系,Go语言提供的 unicode 包和 unicode/utf8 包的使用。
下面话不多说了,来一起看看详细的介绍吧
2 UTF-8 和 Unicode 的关系
Unicode一种字符集,是国际标谁化组织(ISO)设计的一个包括了地球上所有文化、所有字母和符号 的编码。他们叫它 Universal Multiple-Octet Coded Character Set,简称 UCS,也就是 Unicode。Unicode 为每一个 字符 分配一个唯一的 码点(Code Point),就是一个唯一的值。例如 康 的码点就是 24247,十六进制为 5eb7。
Unicode 字符集仅仅定义了字符与码点的对应关系,但是并没有定义该如何编码(存储)这个码值,这就导致了很多问题。例如由于字符的码值不同,导致所需要的存储空间是不一致的,计算机不能确定接下来的字符是占用几个字节。还有就是如果采用固定的长度假设都是4个字节来存储码点值,那么会导致空间的额外浪费,因为 ascii 码字符其实仅仅需要一个字节的空间。
UTF-8 就是解决如何为 Unicode 编码而设计的一种编码规则。可以说 UTF-8 是 Unicode 的实现方式之一。其特点是一种变长编码,使用1到4个字节表示一个字符,根据不同的符号而变化长度。UTF-8 的编码规则有二:
- 对于单字节的符号,字节的第一位设为0,后面7位为这个符号的 Unicode 码。因此对于ASCII码字符,UTF-8 编码和 ASCII 码是相同的。
- 对于 n 字节的符号(n > 1,2到4),第一个字节的前n位都设为1,第n + 1 位设为 0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的 Unicode 码。
以下是编码规则:
Unicode | UTF-8 --------------------------------------------------------- 0000 0000-0000 007F | 0xxxxxxx 0000 0080-0000 07FF | 110xxxxx 10xxxxxx 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx ---------------------------------------------------------
Go语言中,对于 Unicode 和 UTF-8 使用了 unicode 和 unicode/utf8 包来实现,下面是阅读 API 的总结和说明。
3 Unicode 包
Go语言中,提供了 Unicode 包,处理与 Unicode 相关的操作,整理如下:
Is(rangeTab *RangeTable, r rune) bool
检测 rune r 是否在 rangeTable 指定的字符范围内。
rangeTable 一个 Unicode 码值集合,通常使用 unicode 包中定义的集合。
判断字符是否出现在汉字集合中:
unicode.Is(unicode.Scripts["Han"], 'k') // 返回 false unicode.Is(unicode.Scripts["Han"], '康') // 返回 true
In(r rune, ranges …*RangeTable) bool
检测 rune r 是否在多个 rangeTable 指定的字符范围内。
rangeTable 一个 Unicode 码值集合,通常使用 unicode 包中定义的集合。
unicode.In('康', unicode.Scripts["Han"], unicode.Scripts["Latin"]) // 返回 true unicode.In('k', unicode.Scripts["Han"], unicode.Scripts["Latin"]) // 返回 true
IsOneOf(ranges []*RangeTable, r rune) bool
检测 rune r 是否在 rangeTable ranges 指定的字符范围内。与 In 功能类似,推荐使用 In。
IsSpace(r rune) bool
检测字符 rune r 是否是空白字符。在Latin-1字符空间中,空白字符为:
'\t', '\n', '\v', '\f', '\r', ' ', U+0085 (NEL), U+00A0 (NBSP)
其它的空白字符请参见策略Z和属性Pattern_White_Space。
IsDigit(r rune) bool
检测字符 rune r 是否是十进制数字字符。
unicode.IsDigit('9') // 返回 true unicode.IsDigit('k') // 返回 false
IsNumber(r rune) bool
检测字符 rune r 是否是 Unicode 数字字符。
IsLetter(r rune) bool
检测一个字符 rune r 是否是字母
unicode.IsLetter('9') // 返回 false unicode.IsLetter('k') // 返回 true
IsGraphic(r rune) bool
一个字符 rune r 是否是 unicode 图形字符。图形字符包括字母、标记、数字、符号、标点、空白。
unicode.IsGraphic('9') // 返回 true unicode.IsGraphic(',') // 返回 true
IsControl(r rune) bool
检测一个字符 rune r 是否是 unicode 控制字符。
IsMark(r rune) bool
检测一个字符 rune r 是否是标记字符。
IsPrint(r rune) bool
检测一个字符 rune r 是否是的可打印字符,基本与图形字符一致,除ASCII空白字符U+0020。
IsPunct(r rune) bool
检测一个字符 rune r 是否是 unicode标点字符。
unicode.IsPunct('9') // 返回 false unicode.IsPunct(',') // 返回 true
IsSymbol(r rune) bool
检测一个字符 rune r 是否是 unicode 符号字符。
IsLower(r rune) bool
检测一个字符 rune r 是否是小写字母。
unicode.IsLower('h') // 返回 true unicode.IsLower('H') // 返回 false
IsUpper(r rune) bool
检测一个字符 rune r 是否是大写字母。
unicode.IsUpper('h') // 返回 false unicode.IsUpper('H') // 返回 true
IsTitle(r rune) bool
检测一个字符 rune r 是否是Title字符。大部分字符的 Title 格式就是其大写格式,少数字符的 Title 格式是特殊字符,例如 "htmlcode">
unicode.IsTitle('"htmlcode">unicode.To(unicode.UpperCase, 'h') // 返回 HToLower(r rune) rune
将字符 rune r 转换为小写。
unicode.ToLower('H') // 返回 hfunc (SpecialCase) ToLower
将字符 rune r 转换为小写。优先使用映射表 SpecialCase。
映射表 SpecialCase 是特定语言环境下大小写的映射表。主要应用于一些欧洲字符,例如土耳其 TurkishCase。
unicode.TurkishCase.ToLower('"htmlcode">unicode.ToUpper('h') // 返回 Hfunc (SpecialCase) ToUpper
将字符 rune r 转换为大写。优先使用映射表 SpecialCase。
映射表 SpecialCase 是特定语言环境下大小写的映射表。主要应用于一些欧洲字符,例如土耳其 TurkishCase。
unicode.TurkishCase.ToUpper('i') // 返回 "htmlcode">unicode.ToTitle('h') // 返回 Hfunc (SpecialCase) ToTitle
将字符 rune r 转换为 Title 字符。优先使用映射表 SpecialCase。
映射表 SpecialCase 是特定语言环境下大小写的映射表。主要应用于一些欧洲字符,例如土耳其 TurkishCase。
unicode.TurkishCase.ToTitle('i') // 返回 "htmlcode">unicode.SimpleFold('H') // 返回 h unicode.SimpleFold('Φ')) // 返回 φ4 unicode/utf8 包
DecodeLastRune(p []byte) (r rune, size int)
解码 []byte p 中最后一个 UTF-8 编码序列,返回该码值和长度。
utf8.DecodeLastRune([]byte("小韩说课")) // 返回 35838 3 // 35838 就是课的 unicode 码值DecodeLastRuneInString(s string) (r rune, size int)
解码 string s 中最后一个 UTF-8 编码序列,返回该码值和长度。
utf8.DecodeLastRuneInString("小韩说课") // 返回 35838 3 // 35838 就是课的 unicode 码值DecodeRune(p []byte) (r rune, size int)
解码 []byte p 中第一个 UTF-8 编码序列,返回该码值和长度。
utf8.DecodeRune([]byte("小韩说课")) // 返回 23567 3 // 23567 就是 小 的 unicode 码值DecodeRuneInString(s string) (r rune, size int)
解码 string s 中第一个 UTF-8 编码序列,返回该码值和长度。
utf8.DecodeRuneInString("小韩说课") // 返回 23567 3 // 23567 就是 小 的 unicode 码值EncodeRune(p []byte, r rune) int
将 rune r 的 UTF-8 编码序列写入 []byte p,并返回写入的字节数。p 满足足够的长度。
buf := make([]byte, 3) n := utf8.EncodeRune(buf, '康') fmt.Println(buf, n) // 输出 [229 186 183] 3FullRune(p []byte) bool
检测 []byte p 是否包含一个完整 UTF-8 编码。
buf := []byte{229, 186, 183} // 康 utf8.FullRune(buf) // 返回 true utf8.FullRune(buf[:2]) // 返回 falseFullRuneInString(s string) bool
检测 string s 是否包含一个完整 UTF-8 编码。
buf := "康" // 康 utf8.FullRuneInString(buf) // 返回 true utf8.FullRuneInString(buf[:2]) // 返回 falseRuneCount(p []byte) int
返回 []byte p 中的 UTF-8 编码的码值的个数。
buf := []byte("小韩说课") len(buf) // 返回 12 utf8.RuneCount(buf) // 返回 4RuneCountInString(s string) (n int)
返回 string s 中的 UTF-8 编码的码值的个数。
buf := "小韩说课" len(buf) // 返回 12 utf8.RuneCountInString(buf) // 返回 4RuneLen(r rune) int
返回 rune r 编码后的字节数。
utf8.RuneLen('康') // 返回 3 utf8.RuneLen('H') // 返回 1RuneStart(b byte) bool
检测字节 byte b 是否可以作为某个 rune 编码的第一个字节。
buf := "小韩说课" utf8.RuneStart(buf[0]) // 返回 true utf8.RuneStart(buf[1]) // 返回 false utf8.RuneStart(buf[3]) // 返回 trueValid(p []byte) bool
检测切片 []byte p 是否包含完整且合法的 UTF-8 编码序列。
valid := []byte("小韩说课") invalid := []byte{0xff, 0xfe, 0xfd} utf8.Valid(valid) // 返回 true utf8.Valid(invalid) // 返回 falseValidRune(r rune) bool
检测字符 rune r 是否包含完整且合法的 UTF-8 编码序列。
valid := 'a' invalid := rune(0xfffffff) fmt.Println(utf8.ValidRune(valid)) // 返回 true fmt.Println(utf8.ValidRune(invalid)) // 返回 falseValidString(s string) bool
检测字符串 string s 是否包含完整且合法的 UTF-8 编码序列。
valid := "小韩说课" invalid := string([]byte{0xff, 0xfe, 0xfd}) fmt.Println(utf8.ValidString(valid)) // 返回 true fmt.Println(utf8.ValidString(invalid)) // 返回 false完!
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。
相思资源网 Design By www.200059.com
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。