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?

Telaclavo
quelle
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');
Stefan Gehrig
quelle
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}";
Schwarzes Loch
quelle
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.

Pacerier
quelle
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");
Gumbo
quelle
10
html_entity_decode('&#x30a8;', 0, 'UTF-8');

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

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

Probieren Sie Portable UTF-8 aus :

$str = utf8_chr( 0x1000 );
$str = utf8_chr( '\u1000' );
$str = utf8_chr( 4096 );

Alle arbeiten genauso. Sie können den Codepunkt eines Zeichens mit abrufen utf8_ord(). Lesen Sie mehr über Portable UTF-8 .

Hamid Sarfraz
quelle
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
Timo Tijhof
quelle
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);

chings228
quelle