PHP文字列のUnicode文字


164

この質問は恥ずかしいほど簡単に見えますが、答えを見つけることができませんでした。

次のコードのC#行に相当するPHPは何ですか?

string str = "\u1000";

このサンプルは、「Unicode数値」が16進数で1000(10進数で4096)である単一のUnicode文字で文字列を作成します。

つまり、PHPで「Unicode数値」がわかっている単一のUnicode文字を含む文字列を作成するにはどうすればよいですか?



4
@diEcho:これは、一致するUnicode文字の場合のみですが、OPはそれらの文字を作成する必要があります。
Stefan Gehrig

これは役立つかもしれません:randomchaos.com/documents/
source

回答:


178

JSONは\uxxxx構文を直接サポートしているため、最初に頭に浮かぶのは次のとおりです。

$unicodeChar = '\u1000';
echo json_decode('"'.$unicodeChar.'"');

別のオプションは使用することです mb_convert_encoding()

echo mb_convert_encoding('က', 'UTF-8', 'HTML-ENTITIES');

または、UTF-16BE(ビッグエンディアン)とUnicodeコードポイント間の直接マッピングを利用します。

echo mb_convert_encoding("\x10\x00", 'UTF-8', 'UTF-16BE');

9
JSONはJavaScriptではありません。
ガンボ

4
@ガンボ:私はそれを知っていますが、ここでは何の違いもありません。JavaScriptとJSONは\uxxxxUnicode構文をサポートしているため、を使用json_decodeして、人為的に作成されたJSON文字列表現を操作できます。それを明確にするために私は言い回しを変えました。
Stefan Gehrig

3
さて、私の質問に対する1つの回答の厳密な定式化は次のとおりです。$ str = json_decode( '"\ u1000"'); ありがとうございました。
テラクラボ

私が試しecho json_decode('\u201B');にどのreferesを単一引用符を元に戻し、それが動作していないが、何も出力を意味していない(にパイプ場合でもhd
hek2mgl

4
あなたが必要echo json_decode('"\u201B"');です。Unicodeシンボルを囲む二重引用符は必須です。
Stefan Gehrig 2014

162

PHP 7.0.0では、「Unicodeコードポイントエスケープ」構文が導入されています

関数を呼び出さずに、二重引用符またはヒアドキュメント文字列を使用して、Unicode文字を簡単に書き込むことができるようになりました。

$unicodeChar = "\u{1000}";

これには、同様に使用することができる:wordwrap($longLongText, 20, "\u{200B}", true);ゼロ幅のスペースはある)
sanmai

5
OPはこの答えを望んでいると思います。受け入れられた答えではありません。とにかく、「Unicode in PHP」を検索したところ、受け入れられた答えではなく、この答えが欲しかったからです。この質問が最初に尋ねられたとき、「\ u {abcd}」は存在しなかったのかもしれません。その場合は、受け入れられた回答を移動する必要があります。
Adam Chalcraft、

23

なぜ誰もこれについてまだ言及していませんが、二重引用符で囲まれた文字列のエスケープシーケンスを使用して、ほぼ同等のバージョンを実行できます

\x[0-9A-Fa-f]{1,2}

正規表現に一致する文字のシーケンスは、16進表記の文字です。

ASCIIの例:

<?php
    echo("\x48\x65\x6C\x6C\x6F\x20\x57\x6F\x72\x6C\x64\x21");
?>

"こんにちは世界"

したがって、あなたの場合、あなたがする必要があるのはです$str = "\x30\xA2";。ただし、これらは文字ではなくバイトです。Unicodeコードポイントのバイト表現はUTF-16ビッグエンディアンと一致するため、次のように直接出力できます。

<?php
    header('content-type:text/html;charset=utf-16be');
    echo("\x30\xA2");
?>

別のエンコーディングを使用している場合は、それに応じてバイトを変更する必要があります(大部分はライブラリで行われますが、手動でも可能です)。

UTF-16リトルエンディアンの例:

<?php
    header('content-type:text/html;charset=utf-16le');
    echo("\xA2\x30");
?>

UTF-8の例:

<?php
    header('content-type:text/html;charset=utf-8');
    echo("\xE3\x82\xA2");
?>

pack機能もありますが、遅いと思われます。


箇条書き文字(\ xE2 \ x80 \ xA2)をコピーして貼り付けると、ソースドキュメントでUTF-8エンコードエラーが発生する可能性がある場合に最適です。ありがとうございました。
jimp

21

PHPはこれらのUnicodeエスケープシーケンスを認識しません。ただし、不明なエスケープシーケンスは影響を受けないため、このようなUnicodeエスケープシーケンスを変換する独自の関数を作成できます。

function unicodeString($str, $encoding=null) {
    if (is_null($encoding)) $encoding = ini_get('mbstring.internal_encoding');
    return preg_replace_callback('/\\\\u([0-9a-fA-F]{4})/u', create_function('$match', 'return mb_convert_encoding(pack("H*", $match[1]), '.var_export($encoding, true).', "UTF-16BE");'), $str);
}

または、次の代わりに無名関数式を使用しcreate_functionます。

function unicodeString($str, $encoding=null) {
    if (is_null($encoding)) $encoding = ini_get('mbstring.internal_encoding');
    return preg_replace_callback('/\\\\u([0-9a-fA-F]{4})/u', function($match) use ($encoding) {
        return mb_convert_encoding(pack('H*', $match[1]), $encoding, 'UTF-16BE');
    }, $str);
}

その使用法:

$str = unicodeString("\u1000");

10
html_entity_decode('&#x30a8;', 0, 'UTF-8');

これも機能します。ただし、json_decode()ソリューションははるかに高速です(約50倍)。


シンプルでエレガント、簡単、そして完全に安全な方法。+10
andreszs


3

他の人が述べたように、PHP 7 \uではUnicode構文のサポートが直接導入されています。

他の人にも言及されているように、PHPの賢明なUnicode文字記述から文字列値を取得する唯一の方法は、それを別のもの(JSON解析、HTML解析、またはその他の形式など)から変換することです。ただし、これには実行時のパフォーマンスコストが伴います。

ただし、他に1つのオプションがあります。\xバイナリエスケープを使用して、PHPで文字を直接エンコードできます。\xエスケープ構文もされたPHP 5でサポートされています

これは、文字を自然な形で文字列に直接入力したくない場合に特に便利です。たとえば、それが目に見えない制御文字である場合、または空白を検出するのが難しい他の場合です。

まず、証明の例:

// Unicode Character 'HAIR SPACE' (U+200A)
$htmlEntityChar = "&#8202;";
$realChar = html_entity_decode($htmlEntityChar);
$phpChar = "\xE2\x80\x8A";
echo 'Proof: ';
var_dump($realChar === $phpChar); // bool(true)

Pacerierが別の回答で述べたように、このバイナリコードは特定の文字エンコーディングに固有であることに注意してください。上記の例で\xE2\x80\x8Aは、はUTF-8でのU + 200Aのバイナリコーディングです。

次の質問は、どのようにから入手できますさU+200A\xE2\x80\x8A

以下は、ネイティブ文字列として取得したJSON文字列、HTMLエンティティ、またはその他のメソッドに基づいて、任意の文字のエスケープシーケンスを生成するPHPスクリプトです。

function str_encode_utf8binary($str) {
    /** @author Krinkle 2018 */
    $output = '';
    foreach (str_split($str) as $octet) {
        $ordInt = ord($octet);
        // Convert from int (base 10) to hex (base 16), for PHP \x syntax
        $ordHex = base_convert($ordInt, 10, 16);
        $output .= '\x' . $ordHex;
    }
    return $output;
}

function str_convert_html_to_utf8binary($str) {
    return str_encode_utf8binary(html_entity_decode($str));
}
function str_convert_json_to_utf8binary($str) {
    return str_encode_utf8binary(json_decode($str));
}

// Example for raw string: Unicode Character 'INFINITY' (U+221E)
echo str_encode_utf8binary('∞') . "\n";
// \xe2\x88\x9e

// Example for HTML: Unicode Character 'HAIR SPACE' (U+200A)
echo str_convert_html_to_utf8binary('&#8202;') . "\n";
// \xe2\x80\x8a

// Example for JSON: Unicode Character 'HAIR SPACE' (U+200A)
echo str_convert_json_to_utf8binary('"\u200a"') . "\n";
// \xe2\x80\x8a

0
function unicode_to_textstring($str){

    $rawstr = pack('H*', $str);

    $newstr =  iconv('UTF-16BE', 'UTF-8', $rawstr);
    return $newstr;
}

$ msg = '67714eac99c500200054006f006b0079006f002000530074006100740069006f006e003a0020';

echo unicode_to_textstring($ str);

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.