golang中文字符处理

因为中文字符的特殊性,基本上各类语言对于中文字符都需要进行特定的处理。

原理说明

golang中,字符串的底层是通过byte数组来实现的, 我们看下byte的底层结构:

type byte = uint8

可以看到,byte类型的底层实际为uint8类型

字符串的底层结构为:

type StringHeader struct {
	Data uintptr // 指向底层字节数组的指针
	Len  int  // 字符串的字节长度
}

由于golang默认为UTF-8编码,所以,中文进行存储时,如“你好”,会存储为:

“你”编码为\xe4\xbd\xa0,“好”编码为\xe5\xa5\xbd

rune类型底层结构

type rune = int32

rune类型是int32的别名(-231~231-1),对于byte(-128~127),可表示的字符更多。由于rune可表示的范围更大,所以能处理一切字符,当然也包括中文字符。在平时计算中文字符,可用rune。

byte 与 rune对比

func TestOther(t *testing.T) {
	text := "abcd1234浮生无事"
	fmt.Println([]byte(text))
	fmt.Println([]rune(text))
}
byte & rune

通过上面的例子,我们可以直观的看到,rune将字符串拆分为多个Unicode 字符序列,而byte则将其拆分为字节序列。

所以,利用rune就可以解决各类中文字符串计算问题。

中文字符串处理

func TestOther(t *testing.T) {
	text := "abcd1234浮生无事"
	textLen := len(text)
	t.Log("len:" + strconv.FormatInt(int64(textLen), 10))
	for i := 0; i <= textLen - 1; i++ {
		t.Log(fmt.Sprintf("word:%s", text[i:i+1]))
	}
}

可以看到,因为字符串计算是按照字节来计算的,所以,无论是字符串长度,还是字符串切割,都是按照字节来进行,导致中文乱码(注意在golang中一个汉字占3个byte)。

此时,为解决该类情况,正确的对中文进行处理:

func TestOther(t *testing.T) {
	text := "abcd1234浮生无事"
	textRune := []rune(text)
	textLen := len(textRune)
	t.Log("len:" + strconv.FormatInt(int64(textLen), 10))
	for i := 0; i < textLen; i++ {
		t.Log(fmt.Sprintf("word:%s", string(textRune[i])))
	}
}

将字符串,转为[]rune类型后,即可以对中文字符进行正确的处理,不会出现乱码。

易享写作 - 专业在线小说创作工具

🚀 易享写作 - 专业在线小说创作工具

欢迎使用 易享写作 (MakeANovel) —— 一款专为小说创作者设计的在线平台。无论您是网文作家、文学爱好者还是故事创作者,这里都能提供您所需的强大工具。

  • 人物关系图生成器:可视化梳理复杂角色关系,创作更轻松。
  • 在线创作与保存:实时保存,多设备同步,灵感永不丢失。
  • 作品系统管理:清晰管理您的所有小说项目和章节。
  • 便捷分享与反馈:方便获取读者意见,助力作品完善。

4 评论
最新
最旧 最多投票
内联反馈
查看所有评论
滚动至顶部