2011-08-18 48 views
3

是否有一個函數會將UTF-8更改爲Unicode,而將非特殊字符視爲普通字母和數字?UTF-8到Unicode代碼點

即德語單詞「tchüß」將呈現爲類似「tch \ 20AC \ 21AC」(請注意,我正在製作Unicode代碼)。

編輯:我用下面的函數試驗,但儘管這一個ASCII碼32到127的效果很好,它似乎失敗雙字節字符:

function strToHex ($string) 
{ 
    $hex = ''; 
    for ($i = 0; $i < mb_strlen ($string, "utf-8"); $i++) 
    { 
     $id = ord (mb_substr ($string, $i, 1, "utf-8")); 
     $hex .= ($id <= 128) ? mb_substr ($string, $i, 1, "utf-8") : "&#" . $id . ";"; 
} 

    return ($hex); 
} 

任何想法?

編輯2:找到的解決方案:PHP的ord()函數不適用於雙字節字符。改爲使用:http://nl.php.net/manual/en/function.ord.php#78032

+3

標題更改爲更具描述 - UTF-8 ** **是Unicode的。您可能正在尋找「UTF-8到Unicode代碼點」。 – Artyom

+0

一個有用的資源:http://stackoverflow.com/questions/395832/how-to-get-code-point-number-for-a-given-character-in-a-utf-8-string – Karolis

+0

你怎麼樣定義「非特殊字符」? – borrible

回答

2

轉換一個字符集到另一個可以用的iconv來完成:

http://php.net/manual/en/function.iconv.php

需要注意的是UTF已經是Unicode編碼。

另一種方式是僅使用htmlentities用正確的字符集:

http://php.net/manual/en/function.htmlentities.php

+0

'htmlentities'只能轉換在HTML語言中定義了實體的字符,但它只涵蓋Unicode的一小部分。不幸的是,它不會爲其他字符創建'&#...;'字符引用。 – bobince

+0

我知道,但'iconv'往往會帶來一些問題。並不是所有的角色都能夠完美地轉換爲每個字符集。這就是爲什麼我提到'htmlentities'功能。在'iconv'功能頁面的評論中也有人提出:http://nl.php.net/manual/en/function.iconv.php#81494 – Luwe

2

我想你會在網站上打印出你的字符串?

我在輸出前使用html_entities($ string)將所有數據庫存儲在uft8中。你可能需要嘗試一下 html_entities(utf8_encode($ string));

2

我曾經創建了一個名爲_convert()功能,安全編碼一切UTF-8。

+1

你可以在這裏添加答案,而不是作爲鏈接。 – eis

19

對於可讀格式,我會用JSON去。它不需要逃避JSON非ASCII字符,但PHP的作用:

echo json_encode("tchüß"); 

"tch\u00fc\u00df" 
+1

有趣,從來沒有想過這個! –

+1

太棒了!工程就像一個魅力.. :) – Anthony

7

爲人們尋找,找到的Unicode碼點,這可能是有用的任何字符。然後,您可以根據需要對字符串進行編碼,用轉義碼替換某些字符,並將其他字符保留爲二進制形式(例如ascii可打印字符),具體取決於您要使用它的上下文。

來自:Mapping codepoints to Unicode encoding forms

爲UTF-32的映射是,本質上,身份映射:用於編碼一個碼點的 32位代碼單元具有相同的整數值 作爲碼點本身。

/** 
* Convert a string into an array of decimal Unicode code points. 
* 
* @param $string [string] The string to convert to codepoints 
* @param $encoding [string] The encoding of $string 
* 
* @return [array] Array of decimal codepoints for every character of $string 
*/ 
function toCodePoint($string, $encoding) 
{ 
    $utf32 = mb_convert_encoding($string, 'UTF-32', $encoding); 
    $length = mb_strlen($utf32, 'UTF-32'); 
    $result = []; 


    for($i = 0; $i < $length; ++$i) 

     $result[] = hexdec(bin2hex(mb_substr($utf32, $i, 1, 'UTF-32'))); 


    return $result; 
} 
0

我有一個問題,當我需要與cyrilic字符串轉換(UTF-8在默認情況下)的實體部分 - 只有cyrilic。 Finaly我需要得到JSON樣的結果,像這樣:

<li class="my_class">City - Mocsow (Москва)</li> 

這樣:

<li class=\"my_class\">City - Mocsow (\u041c\u043e\u0441\u043a\u0432\u0430)<\/li> 

所以,i`ve得到了COMPEX溶液(SUBJ作者及Nus的組合。):

function strToHex($string){ 
    $enc="utf-8"; 
    $hex = ''; 
    for ($i = 0; $i < mb_strlen ($string, $enc); $i++){ 
     $id = ord (mb_substr ($string, $i, 1, $enc)); 
     $hex .= ($id <= 128) ? mb_substr ($string, $i, 1, $enc) : toCodePoint(mb_substr ($string, $i, 1, $enc), $enc); 
    } 
    return $hex; 
} 
function toCodePoint($string, $encoding){ 
    $utf32 = mb_convert_encoding($string, 'UTF-32', $encoding); 
    $length = mb_strlen($utf32, 'UTF-32'); 
    $result = Array(); 
    for($i = 0; $i < $length; ++$i)$result[] = "\u".substr(bin2hex(mb_substr($utf32, $i, 1, 'UTF-32')), 4,8); 
    return implode("", $result); 
} 
$output=strToHex(
    str_replace(// this is for json compatible 
     array("\"", "\n", "\r", "\t", "/"), 
     array('\"', '\n', "", " ", "\/"), 
     $text 
    ) 
); 
echo $output; 

它測試的PHP 5.2.17 :)

3

隨着PHP 7,有一個新的IntlChar::ord()從給定的UTF-8字符找到Unicode代碼點:

var_dump(sprintf('U+%04X', IntlChar::ord('ß'))); 

# Outputs: string(6) "U+00DF" 
+0

請注意,您需要在PHP.ini中啓用extension = php_intl.dll以使此類存在。 – eis

0

測試在PHP 5.6

/** 
* @param string $utf8char 
* @return string 
*/ 
function toUnicodeCodePoint($utf8char) 
{ 
    return 'U+' . dechex(mb_ord($utf8char)); 
} 

/** 
* @see https://github.com/symfony/polyfill-mbstring 
* @param string $s 
* @return int 
*/ 
function mb_ord($s) 
{ 
    $code = ($s = unpack('C*', substr($s, 0, 4))) ? $s[1] : 0; 
    if (0xF0 <= $code) { 
     return (($code - 0xF0) << 18) + (($s[2] - 0x80) << 12) + (($s[3] - 0x80) << 6) + $s[4] - 0x80; 
    } 
    if (0xE0 <= $code) { 
     return (($code - 0xE0) << 12) + (($s[2] - 0x80) << 6) + $s[3] - 0x80; 
    } 
    if (0xC0 <= $code) { 
     return (($code - 0xC0) << 6) + $s[2] - 0x80; 
    } 

    return $code; 
} 

echo toUnicodeCodePoint(''); 
// U+1f613