河南省示范校建设专题网站,中国建设银行账户查询,怎么样让公司网站,苏州企业网站设计本文介绍两个含中文的字符串且针对相同位置字符的比较#xff0c;给出实现代码。 起因
某工程需将接收的字符串和数据库里的指定字段值对比#xff0c;该字符串含中文#xff0c;两者允许个别字符有差异#xff0c;差异数量3及以下的#xff0c;认为相同。
字符串默认用…本文介绍两个含中文的字符串且针对相同位置字符的比较给出实现代码。 起因
某工程需将接收的字符串和数据库里的指定字段值对比该字符串含中文两者允许个别字符有差异差异数量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