0

重複の可能性:
テキストを PHP を使用して \u0054\u0068\u0069\u0073 のような Unicode コード ポイントに変換する方法は?

7 ビット ANSI 文字に収まらないすべての文字をエスケープ形式に変換しようとしています。\uNここで、Nはその 10 進数値です。これが私が思いついたものです:

private static function escape($str) {
    return preg_replace_callback('~[\\x{007F}-\\x{FFFF}]~u',function($m){return '\\u'.ord($m[0]);},$str);
}

ガンマのようなキャラクターで試してみました

echo self::escape('Γ');

しかし、私は\u206代わりに戻ってきます\u915。どこが間違っているのかわかりません...アイデアですか?

実際、ord()関数が値を提供しないか、必要な値を提供しないか、または .php ファイルのエンコーディングが間違っているように見えますか?

4

1 に答える 1

4

UTF-8 が正確にどのように機能するかについて記憶を新たにする必要がありましたが、ここにutf8_ord()関数と補完的なutf8_chr(). これは、私の回答herechr()からほぼ逐語的に持ち上げられています。

function utf8_ord ($chr)
{
    $bytes = array_values(unpack('C*', $chr));

    switch (count($bytes)) {
        case 1:
            return $bytes[0] < 0x80
                ? $bytes[0]
                : false;
        case 2:
            return ($bytes[0] & 0xE0) === 0xC0 && ($bytes[1] & 0xC0) === 0x80
                ? (($bytes[0] & 0x1F) << 6) | ($bytes[1] & 0x3F)
                : false;
        case 3:
            return ($bytes[0] & 0xF0) === 0xE0 && ($bytes[1] & 0xC0) === 0x80 && ($bytes[2] & 0xC0) === 0x80 
                ? (($bytes[0] & 0x0F) << 12) | (($bytes[1] & 0x3F) << 6) | ($bytes[2] & 0x3F)
                : false;
        case 4:
            return ($bytes[0] & 0xF8) === 0xF0 && ($bytes[1] & 0xC0) === 0x80 && ($bytes[2] & 0xC0) === 0x80 && ($bytes[3] & 0xC0) === 0x80
                ? (($bytes[0] & 0x07) << 18) | (($bytes[1] & 0x3F) << 12) | (($bytes[2] & 0x3F) << 6) | ($bytes[3] & 0x3F)
                : false;
    }

    return false;
}

function utf8_chr ($ord)
{
    switch (true) {
        case $ord < 0x80:
            return pack('C*', $ord & 0x7F);
        case $ord < 0x0800:
            return pack('C*', (($ord & 0x07C0) >> 6) | 0xC0, ($ord & 0x3F) | 0x80);
        case $ord < 0x010000:
            return pack('C*', (($ord & 0xF000) >> 12) | 0xE0, (($ord & 0x0FC0) >> 6) | 0x80, ($ord & 0x3F) | 0x80);
        case $ord < 0x110000:
            return pack('C*', (($ord & 0x1C0000) >> 18) | 0xF0, (($ord & 0x03F000) >> 12) | 0x80, (($ord & 0x0FC0) >> 6) | 0x80, ($ord & 0x3F) | 0x80);
    }

    return false;
}
于 2012-10-11T21:35:44.023 に答える