Unicode-Zeichen in PHP-Zeichenfolge


163

Diese Frage sieht peinlich einfach aus, aber ich konnte keine Antwort finden.

Was entspricht PHP der folgenden C # -Codezeile?

string str = "\u1000";

In diesem Beispiel wird eine Zeichenfolge mit einem einzelnen Unicode-Zeichen erstellt, dessen "numerischer Unicode-Wert" 1000 hexadezimal (4096 dezimal) beträgt.

Wie kann ich in PHP eine Zeichenfolge mit einem einzelnen Unicode-Zeichen erstellen, dessen "numerischer Unicode-Wert" bekannt ist?



4
@diEcho: Das ist nur zum Abgleichen von Unicode-Zeichen, aber das OP möchte diese Zeichen erstellen.
Stefan Gehrig


Antworten:


178

Da JSON die \uxxxxSyntax direkt unterstützt , fällt mir als Erstes Folgendes ein:

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

Eine andere Option wäre zu verwenden mb_convert_encoding()

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

oder nutzen Sie die direkte Zuordnung zwischen UTF-16BE (Big Endian) und dem Unicode-Codepunkt:

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

9
JSON ist kein JavaScript.
Gumbo

4
@Gumbo: Ich weiß das, aber es macht hier keinen Unterschied. Javascript und JSON unterstützen die \uxxxxUnicode-Syntax, sodass Sie json_decodean einer künstlich erstellten JSON-Zeichenfolgendarstellung arbeiten können. Ich habe den Wortlaut geändert, um dies zu klären.
Stefan Gehrig

3
Ok, die strikte Formulierung einer Antwort auf meine Frage lautet: $ str = json_decode ('"\ u1000"'); Danke dir.
Telaclavo

Ich habe versucht, echo json_decode('\u201B');was sich auf ein einzelnes rückgängig gemachtes Zitat bezieht. Es funktioniert jedoch nicht, was bedeutet, dass keine Ausgabe erfolgt (auch wenn es an eine hd
Leitung weitergeleitet wird

4
Du brauchst echo json_decode('"\u201B"');. Doppelte Anführungszeichen um das Unicode-Symbol sind obligatorisch.
Stefan Gehrig

161

PHP 7.0.0 hat die Syntax "Unicode Codepoint Escape" eingeführt .

Es ist jetzt möglich, Unicode-Zeichen einfach mit einem doppelten oder einem Heredoc- String zu schreiben , ohne eine Funktion aufzurufen.

$unicodeChar = "\u{1000}";

Dies kann wie wordwrap($longLongText, 20, "\u{200B}", true);
folgt

5
Ich glaube, das OP wollte diese Antwort, nicht die akzeptierte Antwort. Als ich nach "Unicode in PHP" suchte, wollte ich jedenfalls diese Antwort, nicht die akzeptierte Antwort. Vielleicht existierte "\ u {abcd}" nicht, als diese Frage zum ersten Mal gestellt wurde. In diesem Fall sollte die akzeptierte Antwort jetzt verschoben werden.
Adam Chalcraft

23

Ich frage mich, warum dies noch niemand erwähnt hat, aber Sie können eine fast gleichwertige Version mit Escape-Sequenzen in doppelten Anführungszeichen erstellen :

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

Die Zeichenfolge, die dem regulären Ausdruck entspricht, ist ein Zeichen in hexadezimaler Schreibweise.

ASCII-Beispiel:

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

Hallo Welt!

Für Ihren Fall müssen Sie also nur noch etwas tun $str = "\x30\xA2";. Dies sind jedoch Bytes , keine Zeichen. Die Bytedarstellung des Unicode-Codepunkts stimmt mit dem UTF-16-Big-Endian überein, sodass wir ihn direkt als solchen ausdrucken können:

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

Wenn Sie eine andere Codierung verwenden, müssen Sie die Bytes entsprechend ändern (meistens mit einer Bibliothek, aber auch von Hand möglich).

UTF-16 Little Endian Beispiel:

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

UTF-8-Beispiel:

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

Es gibt auch die packFunktion, aber Sie können erwarten, dass sie langsam ist.


Perfekt für das Kopieren / Einfügen eines Aufzählungszeichens (\ xE2 \ x80 \ xA2), das zu einem UTF-8-Codierungsfehler im Quelldokument führen kann. Danke dir.
Jimp

21

PHP kennt diese Unicode-Escape-Sequenzen nicht. Da unbekannte Escape-Sequenzen jedoch nicht betroffen sind, können Sie eine eigene Funktion schreiben, die solche Unicode-Escape-Sequenzen konvertiert:

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);
}

Oder mit einem anonymen Funktionsausdruck anstelle von 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);
}

Seine Verwendung:

$str = unicodeString("\u1000");

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

Das funktioniert auch. Die json_decode () -Lösung ist jedoch viel schneller (ungefähr 50-mal).


Einfache, elegante, unkomplizierte und absolut sichere Methode. +10
andreszs


3

Wie von anderen erwähnt, führt PHP 7 die \udirekte Unterstützung der Unicode-Syntax ein.

Wie auch von anderen erwähnt, besteht die einzige Möglichkeit, einen Zeichenfolgenwert aus einer sinnvollen Unicode-Zeichenbeschreibung in PHP zu erhalten, darin, ihn von etwas anderem zu konvertieren (z. B. JSON-Analyse, HTML-Analyse oder einer anderen Form). Dies ist jedoch mit Leistungskosten zur Laufzeit verbunden.

Es gibt jedoch noch eine andere Option. Sie können das Zeichen direkt in PHP mit \xbinärem Escapezeichen codieren . Die \xEscape-Syntax wird auch in PHP 5 unterstützt .

Dies ist besonders nützlich, wenn Sie das Zeichen aufgrund seiner natürlichen Form nicht direkt in eine Zeichenfolge eingeben möchten. Zum Beispiel, wenn es sich um ein unsichtbares Steuerzeichen oder ein anderes schwer zu erkennendes Leerzeichen handelt.

Zunächst ein Beweisbeispiel:

// 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)

Beachten Sie, dass dieser Binärcode, wie von Pacerier in einer anderen Antwort erwähnt, für eine bestimmte Zeichenkodierung eindeutig ist. Im obigen Beispiel \xE2\x80\x8Aist die Binärcodierung für U + 200A in UTF-8.

Die nächste Frage ist, wie kommst du von U+200Azu \xE2\x80\x8A?

Unten finden Sie ein PHP-Skript zum Generieren der Escape-Sequenz für ein beliebiges Zeichen, basierend auf einer JSON-Zeichenfolge, einer HTML-Entität oder einer anderen Methode, sobald Sie diese als native Zeichenfolge haben.

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);

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.