对于使用javascript编程的人来说,判断字符串长度应该是常用又简单的操作,但在判断包含有中文字符或其他非asci字符的字符串长度时,却有些坑在里面。
先看看最常用的做法,也就是使用String.length判断:
- let str = "你好奥";
- let len = str.length;
- console.log(len);
- //打印出来的结果时 3
这个输出结果显然是不对的,因为一个汉字实际占用2个字节(GB2312编码)或3个字节(utf8编码)。
看到网上有不少同学,将非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>testtitle>
- 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