2011-08-18 47 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