半角全角的處理是字符串處理的常見問題,本文嘗試為大家提供一個思路。
一、概念
全角字符unicode編碼從65281~65374 (十六進制 0xFF01 ~ 0xFF5E)
半角字符unicode編碼從33~126 (十六進制 0x21~ 0x7E)
空格比較特殊,全角為 12288(0x3000),半角為 32 (0x20)
而且除空格外,全角/半角按unicode編碼排序在順序上是對應的
所以可以直接通過用+-法來處理非空格數據,對空格單獨處理
二、實現思路
1. 找到目標unicode的字符,可以使用正則表達式解決
2. 修改unicode編碼
三、實現
1. 首先是兩個unicode與字符的轉換函數:
1 /**
2 * 將unicode轉換成字符
3 * @param int $unicode
4 * @return string UTF-8字符
5 **/
6 function unicode2Char($unicode){
7 if($unicode < 128) return chr($unicode);
8 if($unicode < 2048) return chr(($unicode >> 6) + 192) .
9 chr(($unicode & 63) + 128);
10 if($unicode < 65536) return chr(($unicode >> 12) + 224) .
11 chr((($unicode >> 6) & 63) + 128) .
12 chr(($unicode & 63) + 128);
13 if($unicode < 2097152) return chr(($unicode >> 18) + 240) .
14 chr((($unicode >> 12) & 63) + 128) .
15 chr((($unicode >> 6) & 63) + 128) .
16 chr(($unicode & 63) + 128);
17 return false;
18 }
19
20 /**
21 * 將字符轉換成unicode
22 * @param string $char 必須是UTF-8字符
23 * @return int
24 **/
25 function char2Unicode($char){
26 switch (strlen($char)){
27 case 1 : return ord($char);
28 case 2 : return (ord($char{1}) & 63) |
29 ((ord($char{0}) & 31) << 6);
30 case 3 : return (ord($char{2}) & 63) |
31 ((ord($char{1}) & 63) << 6) |
32 ((ord($char{0}) & 15) << 12);
33 case 4 : return (ord($char{3}) & 63) |
34 ((ord($char{2}) & 63) << 6) |
35 ((ord($char{1}) & 63) << 12) |
36 ((ord($char{0}) & 7) << 18);
37 default :
38 trigger_error('Character is not UTF-8!', E_USER_WARNING);
39 return false;
40 }
41 }
2. 全角轉半角
1 /**
2 * 全角轉半角
3 * @param string $str
4 * @return string
5 **/
6 function sbc2Dbc($str){
7 return preg_replace(
8 // 全角字符
9 '/[\x{3000}\x{ff01}-\x{ff5f}]/ue',
10 // 編碼轉換
11 // 0x3000是空格,特殊處理,其他全角字符編碼-0xfee0即可以轉為半角
12 '($unicode=char2Unicode(\'\0\')) == 0x3000 ? " " : (($code=$unicode-0xfee0) > 256 ? unicode2Char($code) : chr($code))',
13 $str
14 );
15 }
3. 半角轉全角
1 /**
2 * 半角轉全角
3 * @param string $str
4 * @return string
5 **/
6 function dbc2Sbc($str){
7 return preg_replace(
8 // 半角字符
9 '/[\x{0020}\x{0020}-\x{7e}]/ue',
10 // 編碼轉換
11 // 0x0020是空格,特殊處理,其他半角字符編碼+0xfee0即可以轉為全角
12 '($unicode=char2Unicode(\'\0\')) == 0x0020 ? unicode2Char(0x3000) : (($code=$unicode+0xfee0) > 256 ? unicode2Char($code) : chr($code))',
13 $str
14 );
15 }
四、測試
示例代碼:
1 $a = 'abc12 345'; 2 $sbc = dbc2Sbc($a); 3 $dbc = sbc2Dbc($sbc); 4 5 var_dump($a, $sbc, $dbc);
結果:
1 string(9) "abc12 345" 2 string(27) "abc12 345" 3 string(9) "abc12 345"