Golang实践录:一个字符串比较示例
Posted 李迟
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Golang实践录:一个字符串比较示例相关的知识,希望对你有一定的参考价值。
本文介绍两个含中文的字符串且针对相同位置字符的比较,给出实现代码。
起因
某工程需将接收的字符串和数据库里的指定字段值对比,该字符串含中文,两者允许个别字符有差异,差异数量3及以下的,认为相同。
字符串默认用 string,于是想当然使用循环遍历,逐个字符对比之,还使用了strings.EqualFold
函数,测试才发现,如果是有中文的话,结果不准确。
分析
Golang 语言的中文使用 uf-8存储,其长度并不固定。以字符串岑溪450481
和芩溪458481
为例,肉眼可见,长度均为8,第一个中文和第三个数字不同,因此差异数量为2,按需求,应认为两个字符串相同。但用 string 对比,结果是不相同,将所有字符打印如下:
次数 字符1 字符2 字符1 字符2
[0] å è 229 232
[1] ² 178 138
[2] © 145 169
[3] æ æ 230 230
[4] º º 186 186
[5] ª ª 170 170
[6] 4 4 52 52
[7] 5 5 53 53
[8] 0 8 48 56
[9] 4 4 52 52
[10] 8 8 56 56
[11] 1 1 49 49
可以看到,上述字符串的长度为12,共有4个地方不同,因此对比后认为不相同。
而用 rune 类型存储,再对比,所有字符如下:
次数 字符1 字符2 字符1 字符2
[0] 岑 芩 23697 33449
[1] 溪 溪 28330 28330
[2] 4 4 52 52
[3] 5 5 53 53
[4] 0 8 48 56
[5] 4 4 52 52
[6] 8 8 56 56
[7] 1 1 49 49
可以看到,字符串长度为8,和肉眼认为的一致,共有2个地方不同,因此对比后认为相同。
测试
函数封装如下:
func String2Rune(src string) (dest []rune)
for _, item := range src
dest = append(dest, item)
return
func checkString(aaa_str, bbb_str string) bool
sameCnt := 0
// 用此法对比不准确
if len(aaa_str) == len(bbb_str)
for i := 0; i < len(bbb_str); i++
if strings.EqualFold(string(aaa_str[i]), string(bbb_str[i]))
sameCnt++
if sameCnt >= len(bbb_str)-3
return true
return false
func checkRune(aaa_str, bbb_str string) bool
sameCnt := 0
// 如有中文,用rune类型
aa_str := String2Rune(aaa_str)
bb_str := String2Rune(bbb_str)
if len(aa_str) == len(bb_str)
for i := 0; i < len(aa_str); i++
if aa_str[i] == bb_str[i]
sameCnt++
if sameCnt >= len(bb_str)-3
return true
return false
为测试对比,设置对比两组数据,以人易理解角度看,分别相差0、1、2、3、4个字符,由实现代码如,相差3及以下字符认为相等,因此只有最后的一项数据不同。
代码如下:
func TestStringNum(t *testing.T)
var a []string = []string"岑溪450481", "岑溪450481", "岑溪450481", "岑溪450481", "岑溪450481"
var b []string = []string"岑溪450481", "芩溪450481", "芩溪458481", "梧州450487", "梧州458487"
for i := 0; i < len(a); i++
fmt.Printf("%v string result: %v %v\\n", i, checkString(a[i], b[i]), checkRune(a[i], b[i]))
测试结果如下:
go test -run TestStringNum
0 string result: true true
1 string result: true true
2 string result: false true
3 string result: false true
4 string result: false false
PASS
小结
如涉及中文字符,因为utf8字符长度不固定,最好用rune类型比较。
李迟 2023.02.20
以上是关于Golang实践录:一个字符串比较示例的主要内容,如果未能解决你的问题,请参考以下文章