1. 程式人生 > >淺談ThinkPhp裡的utf8格式字串擷取

淺談ThinkPhp裡的utf8格式字串擷取

     定義,UTF8是一種unicode的變長通用轉換格式字元編碼, 用1-6個位元組來編碼所有的Unicode字元。

     好處,這個字元編碼可以編碼幾乎所有語言的字元,同時在表示ASCII碼可以表示的字元時編碼和ASCII碼完全一樣,即相容ASCii碼。

     轉換,和unicode轉換的方式是將unicode編碼值轉換成2進位制,從低位開始每6位做一個分割,填充到下面UTF8各個長度編碼模板中的x處。

              一個位元組     0xxxxxxx

             兩個位元組      110xxxxx      10xxxxxx

             三個位元組      1110xxxx      10xxxxxx    10xxxxxx

             四個位元組      11110xxx      10xxxxxx    10xxxxxx   10xxxxxx

             五個位元組      111110xx      10xxxxxx    10xxxxxx   10xxxxxx   10xxxxxx

    六個位元組      1111110x     10xxxxxx    10xxxxxx   10xxxxxx   10xxxxxx   10xxxxxx

比如說unicode的 u0030     對應的UTF8字元編碼: 00110000

                                uFAFA    對應的UTF8字元編碼: 11001111   10101011  10111010

進入正題,貼程式碼:


$want_length    //想要擷取的長度
$orgin_str          //原始字串
$orgin_str_lengh  //原始字元長度
$need_cut_bytes =0;  //需要擷取的位元組數 
$current_length = 0;    //當前擷取位元組數對應的字元數
$fisrt_byte_ascII  //UTF8編碼字元首個位元組的編碼值
$single_char_bytes //單個字元佔的位元組數
for($i =0; $i < $orgin_str_length; ) {
	$first_byte_ascII = ord($orgin_str[$i]); //獲取ascII碼值
	if($first_byte_ascII < 128)  {    //處理utf8單位元組編碼,比32小的是控制符
		$single_char_bytes   = 1;
		$ctr_but_display_chars = array(9, 10);  //水平製表符、回車符等控制符算一個顯示字元  
                // ascii碼小於32的是控制符,跳過讀取下一個字元
		if(!in_array($first_byte_ascII, $ctr_but_display_chars) &&$first_byte_ascII < 32){
			$i++;
			$need_cut_bytes += $single_char_bytes;
			continue;  
		}
	} 
        // UTF8 編碼中無  128 - 191 這種編碼,所以對於utf8字串這個判斷不會進來
	else if($first_byte_ascII  < 192) {
	} 
	else if($first_byte_ascII  < 224) {  //處理utf8  2位元組編碼
		$single_char_bytes   = 2;
	}
	else if($first_byte_ascII  < 240) { //處理utf8  3位元組編碼
		$single_char_bytes = 3
	}
	else if($first_byte_ascII  < 248) { //處理utf8  4位元組編碼
		$single_char_bytes   = 4;
	}
	else if($first_byte_ascII  < 252) { //處理utf8  5位元組編碼	
		$single_char_bytes   = 5;
	}
	else if($first_byte_ascII  < 254) { //處理utf8  6位元組編碼
		$single_char_bytes   = 6;
	}
	$current_length ++; //當前擷取位元組數對應的字元數目自增1   
	$need_cut_bytes += $single_char_bytes;
	$i += $single_char_bytes;
	if($current_length >=$want_length ){ //當前擷取位元組數對應的字元數大於想要擷取的字元數時,跳出迴圈
		break;
	}
}