那天对着编辑器发呆,一直在琢磨如何计算字符串的长度,敲了一段文字跑出来,返回的数字和我肉眼数出来的完全不一样,盯着屏幕盯了好久,越算越乱。

一开始想的很简单,一个字就占一个位置,手动点着数,标点也算进去,那段文本里面有汉字,有英文小写字母,还有两个半角的逗号,数完记下一个数字,再运行代码拿结果,两个数差了好大一截。反复数了两遍,确认自己没有数错,就开始怀疑是不是哪里输入的时候藏了看不见的东西,空格、换行符这类,在界面上看不到,但是程序会把它也算成字符。

删掉所有多余空白,再跑一次。差值还在。

旁边工位的人路过瞟了一眼,随口说了一句,中文和英文占的字节不一样。那一下脑子没转过来,还固执的觉得,我要的是有多少个字,不是占多大存储空间,字节长度跟字符长度本来就不该是一回事。手上也没换别的写法,就继续用原来那行语句反复测试,一会全放英文,数字就和手数的对上,只要掺上汉字,结果就跑偏,来回切换测试文本,心里乱糟糟的。

同一个文本,换不同的编码去看,出来的数值又变了。

那段时间分不清这两个概念,一会把字节数当成字符串长度拿去用,一会又拿着肉眼统计的字符个数去对标字节返回值,来回来回绕。复制了一句很短的话,就五个汉字加一个英文符号,手数是六,跑出来有的地方返回六,有的地方返回十一,看着两个不一样的数字,不知道该信哪一个,也不清楚业务那边想要的到底是哪一种统计方式。

后来才反应过来,我一直没问清楚需求。

写这段逻辑的时候默认需求就是单纯数有多少个可见字符,但是别的同事之前写的旧代码,默认拿的是字节数量,数据库里面存文本的时候,也是按字节限制长度。这下就撞在一起了,前端展示校验用字符数,入库判断用字节数,混在一起写,校验规则就乱套,输入框明明看着文字不多,提交的时候直接报错超长,用户那边点提交,弹窗弹出来,自己还得去查到底是哪里的判断写反了。

改的时候先分开写了两段,一段用来统计字符个数,一个汉字、字母、标点都单独算作一个,另一段单独统计字节占用,交给入库校验用。拿之前出问题的那段文字重新跑,两个数字分开打印在控制台,这下终于能分清,哪个是给界面提示用,哪个是给存储限制用。只是改完之后心里还是犯嘀咕,是不是还有别的看不见的字符,像全角空格、零宽字符这类东西,就算肉眼看不到,统计的时候照样会被计入,之前踩的坑说不定还会再来一次。

试着粘贴了一段网上复制来的文案,里面藏了看不见的特殊字符,字符统计的数字又悄悄多了一个,肉眼反复扫好几遍,怎么都找不到多出来的那一个东西在哪。

花了不少时间一点点剔除,把这类隐藏字符过滤掉之后,统计结果才和自己手动清点的对上。到这时候才明白,不是计算的写法有对错,只是不同场景,要的根本不是同一个数字。有时候别人嘴上说要字符串长度,心里实际想的是字节长度,不提前确认,写出来的东西看着能跑,等到上线,就冒出一堆莫名其妙的校验异常。

只是我当时的处理方式,只适合我那天碰到的场景,别的语言或者别的项目框架里面,处理方式可能完全不一样,换一套环境,同样一段文字,统计出来的结果又会出现偏差。

关掉编辑器的时候天色已经暗了,屏幕上还留着两行打印出来的数字,并排摆着。