对于使用javascript编程的人来说,判断字符串长度应该是常用又简单的操作,但在判断包含有中文字符或其他非asci字符的字符串长度时,却有些坑在里面。
错误做法1
先看看最常用的做法,也就是使用String.length判断:
let str = "你好奥";
let len = str.length;
console.log(len);
//打印出来的结果时 3
这个输出结果显然是不对的,因为一个汉字实际占用2个字节(GB2312编码)或3个字节(utf8编码)。
错误做法2
看到网上有不少同学,将非asic字符按2个字符来计算,这个也是不对的,这种方法只有在GB2312编码时有效,而实际上网页有的采用GB2312,更多的采用utf8。
let str = "你好奥";
let len = 0;
for(var i = 0; i < str.length; i++){
charCode = str.charCodeAt(i);
if (charCode >= 0 && charCode <= 128) {
len += 1;
}else{
len += 2;
}
}
console.log(len);
//还有这样做的:
console.log(str.replace(/[\u0391-\uFFE5]/g,"aa").length);
这两种方法犯同样的错误,就是想当然的认为时GB2312编码。
正确的做法
第一种是用TextEncoder,这个需要浏览器支持,有些浏览器如ID是不支持的:
let str = "你好奥";
const encoder = new TextEncoder();
console.log(encoder.encode(str).length);
第二种是用Blob:
let str = "你好奥";
console.log(new Blob([str]).size);
第三种,如果是在做nodejs后台程序,还可以用Buffer来判断:
console.log(Buffer.byteLength(str));
在utf8编码下,这三种方法都输出 9
完整的例子及输出
下面是完整的测试页面:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>test</title>
</head>
<body>
<script>
let str = "你好奥";
console.log(str.length);
let len = 0;
for(var i = 0; i < str.length; i++){
charCode = str.charCodeAt(i);
if (charCode >= 0 && charCode <= 128) {
len += 1;
}else{
len += 2;
}
}
console.log(len);
console.log(str.replace(/[\u0391-\uFFE5]/g,"aa").length);
const encoder = new TextEncoder();
console.log(encoder.encode(str).length);
console.log(new Blob([str]).size);
//for nodejs
//console.log(Buffer.byteLength(str));
</script>
</body>
</html>
输出结果:
3
6
6
9
9