PHP 문자열의 유니 코드 문자


164

이 질문은 당혹스럽게 간단 해 보이지만 답을 찾을 수 없었습니다.

다음 C # 코드 라인과 동등한 PHP는 무엇입니까?

string str = "\u1000";

이 샘플은 "유니 코드 숫자 값"이 16 진수로 1000 (10 진수 4096) 인 단일 유니 코드 문자로 문자열을 만듭니다.

즉, PHP에서 "유니 코드 숫자 값"이 알려진 단일 유니 코드 문자로 문자열을 어떻게 만들 수 있습니까?



4
@diEcho : 이는 유니 코드 문자 만 일치시키기위한 것이지만 OP는 해당 문자를 생성하려고합니다.
Stefan Gehrig 12

이것은 도움이 될 수 있습니다 : randomchaos.com/documents/?source=php_and_unicode
diEcho

답변:


178

JSON이 \uxxxx구문을 직접 지원하기 때문에 가장 먼저 생각하는 것은 다음과 같습니다.

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

다른 옵션은 사용하는 것입니다 mb_convert_encoding()

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

또는 UTF-16BE (big endian)와 유니 코드 코드 포인트 간의 직접 매핑을 사용하십시오.

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

9
JSON은 JavaScript가 아닙니다.
Gumbo

4
@ Gumbo : 알고 있지만 여기서 차이가 없습니다. JSON뿐만 아니라 Javascript는 \uxxxx유니 코드 구문을 지원 하므로 json_decode인공적으로 생성 된 JSON 문자열 표현 작업에 사용할 수 있습니다 . 나는 그것을 명확히하기 위해 문구를 변경했습니다.
Stefan Gehrig

3
좋아, 그래서 내 질문에 대한 하나의 답변의 엄격한 공식은 다음과 같습니다. $ str = json_decode ( ' "\ u1000"'); 감사합니다.
Telaclavo

나는 시도 echo json_decode('\u201B');A를 어떤 referes를 하나의 되돌림 따옴표 (경우에도 파이프에 더 출력을 의미하지, 그것은 작동하지 않습니다하지만 hd)
hek2mgl

4
당신은 필요합니다 echo json_decode('"\u201B"');. 유니 코드 기호 주위에 큰 따옴표는 필수입니다.
Stefan Gehrig

162

PHP 7.0.0은 "유니 코드 코드 포인트 이스케이프"구문을 도입했습니다 .

함수를 호출하지 않고 큰 따옴표heredoc 문자열 을 사용하여 유니 코드 문자를 쉽게 작성할 수 있습니다.

$unicodeChar = "\u{1000}";

이것과 같이 사용될 수있다 wordwrap($longLongText, 20, "\u{200B}", true);( 제로 폭 공간 그 것이다)
삼매

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";. 그러나 이들은 문자가 아닌 바이트 입니다. 유니 코드 코드 포인트의 바이트 표현은 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는 이러한 유니 코드 이스케이프 시퀀스를 모릅니다. 그러나 알려지지 않은 이스케이프 시퀀스는 영향을받지 않으므로 이러한 유니 코드 이스케이프 시퀀스를 변환하는 고유 한 함수를 작성할 수 있습니다.

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유니 코드 구문을 직접 지원합니다 .

다른 사람들이 언급했듯이 PHP의 합리적인 유니 코드 문자 설명에서 문자열 값을 얻는 유일한 방법은 다른 것 (예 : JSON 구문 분석, HTML 구문 분석 또는 다른 형식)에서 변환하는 것입니다. 그러나 이는 런타임 성능 비용으로 발생합니다.

그러나 다른 옵션이 있습니다. \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.