php get str length,String Length 中文字串長度

Javascript 的中文編碼是使用兩個 bytes 來儲存的,而英文、符號等是使用一個 byte 來儲存。

Using length

使用 string.length 來計算長度時,中文字串會被當成是一個字來計算,因為 Javascript 是使用 multiple byte 計算,就像是 php 的 mb_strlen。

Examplevartx="測試&eng";

alert(tx.length);

//output: 6

看到吧不管是中文,英文,都當成一個字來算,所以總共是 6 個字,不過有時候我們並不想把中文字當成一個字來計算,因為中文字明明佔的 byte 數就是比較多,所以來看一下中文編碼吧。

中文編碼

一般使用 big5 為繁體中文編碼,每一個中文字是使用兩個 bytes 來儲存。

UTF-8 編碼則是每一個中文字使用三個 bytes 來儲存。

不過這個算法對 javascript 的中文長度計算是有問題的,首先我寫了一小段 Javascript 程式碼,以及兩個不同編碼的網頁,我先抓取一段 UTF-8編碼的網頁,然後計算他的長度。utf8_data.txt 的內容 = [測試中文eng] ,這個檔案在 linux 系統中看到的檔案大小為 15 bytes,代表一個中文字使用三個 bytes 儲存,不過在 Javascript中抓到的字串長度 = 7。big5_data.txt 的內容 = [測試中文eng],這個檔案在 linux 系統中看到的檔案大小為 11 bytes,代表一個中文字使用二個 bytes 儲存,不過在 Javascript中抓到的字串長度 = 9

View Demo

Examplefor(vari=0;i

c+=""+tx.charCodeAt(i).toString(2)+"
";

k+=""+tx.charCodeAt(i).toString()+"
";

}

document.body.innerHTML+=c;

document.body.innerHTML+=k;

//output

/*

110111000101100

1000101001100110

100111000101101

110010110000111

28204

35430

20013

25991

*/

從上面就可以看出來,雖然我是使用 UTF-8 編碼,不過轉成二進位後,每個中文字都是兩個 bytes 的長度而已(從上面的二進位數字中來看,最多只有 16 個 「0和1」,而一個 byte 有 8 個 bits ,所以是 兩個 bytes)。

計算文字 bytes 數

我將每一個文字轉成數字,再去計算他的二進位的 bit 數,決定文字是使用幾個 byte 來儲存。

兩個不同的編碼頁面,使用 length抓到的結果是不相同的,原因是我寫的 Javascript 是使用 UTF-8 編碼,所以可以正常的計算 UTF-8編碼的內容長度,不過在計算 big5 編碼的內容時,就會因為編碼表的不同,而出現怪怪的結果。

接著我試著在 Javascript 中,把中文字轉成二進位的編碼來看看。

Examplevartx="測試中文";

varc=""

functionstringBytes(c){

varn=c.length,s;

varlen=0;

for(vari=0;i

s=c.charCodeAt(i);

while(s>0){

len++;

s=s>>8;

}

}

returnlen;

}

vartx="測試中文12313";

$(document.body).append(stringBytes(tx));

//output: 13

上個範例中,中文字有四個,數字有五個,每個中文字為 2 bytes ,所以總合長度是 13 bytes 。

不存在三個 bytes 的文字

測試了一下 Javascript 是否有三個 bytes 的文字,結果發現,當編碼的數字大於 65535 時(16 bits),數字又會回到 0 開始計算,所以 Javascript 的編碼表中最多只有 65536 個文字 (包含 0 , 0 ~ 65535)。

Examplevart1=String.fromCharCode(65586);

vart2=String.fromCharCode(50);

if(t1==t2)alert("yes")

//兩個文字都是 2 , (65586 -65536 =50) http://www.puritys.me/docs-blog/article-32 : 這裡可以輸出 HTML 編碼表, 從數字 19968 後開始,就是中文字的編碼表。

Using encodeURIComponent

另一種計算方式是使用 encodeURIComponent ,先使用 encodeURIComponent 將字串進行編碼,之後再用 Regular Expression 計算 bytes 數。

Exampletx="測式中文xxxx";

varstr=encodeURIComponent(tx);

console.log("utf8:"+str);

len=str.replace(/%[A-F\d]{2}/g,'U').length;

console.log("len = "+len);

這個方式可以成功的計算 Big5 & UTF-8 的編碼長度。

get string length from web

如果我們使用 ajax 去抓網頁的資料時, Big5 編碼的頁面會自動被轉換成 UTF-8 的亂碼,這時 encodeURIComponent 就沒辦法計算正確的長度。

用 ajax 從 header 中抓頁面的長度

如果是要抓頁面的size ,可以直接從 header 的資訊中取得,方式如下。

Example//using jquery

vargeturl;

geturl=$.ajax({

type:"get",

url:"b.txt",

beforeSend:function(){

},

success:function(tx){

varheader=geturl.getAllResponseHeaders();

varre=/Content-Length:[\s]([0-9]+)/;

vark=header.match(re);

document.body.innerHTML="length = "+k[1];

}

});

使用 ajax 取得 header 的內容

在 Ajax 回傳的 物件中,使用 method : getAllResponseHeaders,就可以抓到 response header 的內容,範例如下。

Examplevarrequest=null;

try{

request=newXMLHttpRequest();

}catch(trymicrosoft){

try{

request=newActiveXObject("Msxml2.XMLHTTP");

}catch(othermicrosoft){

try{

request=newActiveXObject("Microsoft.XMLHTTP");

}catch(failed){

request=null;

}

}

}

functionajaxResultHeader(){

if(request.readyState==4){

if(request.status==200){

vartx=request.responseText;

varheader=request.getAllResponseHeaders();

console.log("header = "+header);

}else

alert("Error! Request status is "+request.status);

}

}

functionajaxGetHeader(){

varurl="b.txt";

request.open("GET",url,true);

request.onreadystatechange=ajaxResultHeader;

request.setRequestHeader("Content-Type","application/octet-stream");

request.send();

}

ajaxGetHeader();

取得的 header 內容

ExampleDate: Wed, 29 Feb 2012 03:01:23 GMT

Server: Apache/2.2.14 (Win32) DAV/2 mod_ssl/2.2.14 OpenSSL/0.9.8l mod_autoindex_color PHP/5.3.1 mod_apreq2-20090110/2.7.1 mod_perl/2.0.4 Perl/v5.10.1

Last-Modified: Wed, 29 Feb 2012 02:44:38 GMT

Etag: "b00000002859d-827-4ba115319353b"

Accept-Ranges: bytes

Content-Length: 2087

Content-Type: text/plain

使用 ajax 從 content 中取得前 2KB 的Bytes 數

HTTP Request 中本身有個屬性 Range , 可以指定我要取得多少 bytes ,從 x1 ~ x2 bytes ,因為從 Server 端取得的資料就是 2 KB ,這樣就不需要經過 Ajax 的胡亂編碼過程,就能正確的取得bytes數,用法就是在 Request Header 中加入 Range:bytes=0-2000,下面是範例。 ! 使用 Range 抓取片段資料,Http Response 的 status 會等於 206

Examplevarrequest=null;

try{

request=newXMLHttpRequest();

}catch(trymicrosoft){

try{

request=newActiveXObject("Msxml2.XMLHTTP");

}catch(othermicrosoft){

try{

request=newActiveXObject("Microsoft.XMLHTTP");

}catch(failed){

request=null;

}

}

}

functionajaxResult(){

if(request.readyState==4){

if(request.status==200||request.status==206){

vartx=request.responseText;

console.log("content= "+tx);

}else

alert("Error! Request status is "+request.status);

}

}

functionajaxGet(){

varurl="b.txt";

request.open("GET",url,true);

request.onreadystatechange=ajaxResult;

request.setRequestHeader("Content-Type","application/octet-stream");

request.setRequestHeader("Range","bytes=0-2000");

request.send();

}

ajaxGet();

Request Header Example

線上測試,使用 Ajax 抓 page header And content線上測試

HeaderContent

Bytes: from ~Request 測試

備註

bit 運算

在電腦的世界中,數字都是使用二進位來計算的,下面是基本的十進位與二進位對照表。

十進位二進位

210

4100

81000

6110

二進位運算符號 「>>」,「 >> 1」這個是指二進位的數字向右邊移動一格,所以最右邊的數字會被刪除,範例如下。

十進位運算二進位的原始值二進位結果

2 >> 1 = 1101

11 >> 2 = 3111011

8 >> 1 = 41000100

6 >> 1 = 311011

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值