번호에서 유니 코드 문자 만들기


114

Java로 유니 코드 문자를 표시하고 싶습니다. 이렇게하면 잘 작동합니다.

String symbol = "\u2202";

기호는 "∂"와 같습니다. 그게 내가 원하는 것입니다.

문제는 내가 유니 코드 번호를 알고 있고 그로부터 유니 코드 기호를 만들어야한다는 것입니다. 나는 명백한 것을 시도했다.

int c = 2202;
String symbol =  "\\u" + c;

그러나이 경우 symbol은 "\ u2202"와 같습니다. 그것은 내가 원하는 것이 아닙니다.

유니 코드 번호를 알고 있다면 어떻게 심볼을 구성 할 수 있습니까 (하지만 런타임에만 ---- 첫 번째 예제처럼 하드 코딩 할 수 없습니다)?


1
첫 번째 백 슬래시를 제거하여 백 슬래시를 이스케이프하는 대신 유니 코드 시퀀스를 이스케이프합니다. "\\"를 사용하면 "\"를 인쇄하고 유니 코드 문자에 대한 이스케이프 시퀀스의 과거로 사용하지 않으려 고 Java에 알립니다. 첫 번째 것을 제거하면 두 번째 백 슬래시가 아닌 유니 코드 시퀀스를 대신 이스케이프합니다. 적어도 내가 아는 한 최선을 다할 것입니다.
Fund Monica의 소송

답변:


73

그냥 캐스팅 intA를 char. 다음을 String사용하여 변환 할 수 있습니다 Character.toString().

String s = Character.toString((char)c);

편집하다:

Java 소스 코드 ( \u비트) 의 이스케이프 시퀀스는 HEX로되어 있으므로 이스케이프 시퀀스를 재현하려면 int c = 0x2202.


3
그것은 나에게 사각형 상자를주는 것입니다, ࢚. 나에게 "∂"를주지 않습니다.
Paul Reiners 2011-04-07

19
위험 해요, 윌 로빈슨! 유니 코드 코드 포인트 가 반드시 char에 맞지는 않는다는 것을 잊지 마십시오 . 따라서의 값 c이 0x10000보다 작은 지 미리 확인해야합니다. 그렇지 않으면이 접근 방식이 끔찍하게 중단됩니다.
다윗은 주어

1
@NickHartley 죄송합니다. 팔로우하지 마세요 --- 10000에 대해 0x10000을 잘못 읽었나요?
다윗은 주어

10
그래서 내가 '아래'라고 말한 것입니다! 그리고 Java 문자가 0xffff까지만 올라간다는 사실에도 불구하고 유니 코드 코드 포인트는 0xfffff까지 올라간다는 사실을 강조해야합니다. 유니 코드 표준은 Java가 디자인 된 후 변경되었습니다. 요즘 자바 문자는 기술적으로 유니 코드 코드 포인트가 아닌 UTF-16 단어를 보유하고 있으며이를 잊어 버리면 애플리케이션이 이국적인 스크립트를 만날 때 끔찍한 손상을 입힐 수 있습니다.
다윗은 주어

3
@DavidGiven 감사합니다 Java chars go up to 0xFFFF. 난 몰랐어.
Tony Ennis

128

UTF-16으로 인코딩 된 코드 단위를로 가져 오려면 char정수를 구문 분석하고 다른 사람이 제안한대로 캐스트 할 수 있습니다.

모든 코드 포인트를 지원하려면 Character.toChars(int). 이것은 코드 포인트가 단일 항목에 맞지 않는 경우를 처리합니다.char 값에 합니다.

Doc 말한다 :

지정된 문자 (유니 코드 코드 포인트)를 char 배열에 저장된 UTF-16 표현으로 변환합니다. 지정된 코드 포인트가 BMP (Basic Multilingual Plane 또는 Plane 0) 값인 경우 결과 char 배열은 codePoint와 동일한 값을 갖습니다. 지정된 코드 포인트가 보조 코드 포인트 인 경우 결과 char 배열에는 해당하는 서로 게이트 쌍이 있습니다.


이것이보다 일반적인 해결책이고 많은 경우에 받아 들여진 대답보다 이것을 사용해야하지만 받아 들여진 대답은 Paul이 요구 한 특정 문제와 더 가깝습니다.
Jochem Kuijpers

2
첫째, 감사합니다! Scala에서는 여전히 char. scala> "👨‍🎨".map(_.toInt).flatMap((i: Int) => Character.toChars(i)).map(_.toHexString)주는 res11: scala.collection.immutable.IndexedSeq[String] = Vector(f468, 200d, f3a8) 세 개의 코드 포인트로 해결되는이 이모티콘, "남성 가수" U+1f468, U+200dU+1f3a8. 최상위 숫자가 누락되었습니다. 비트 OR ( stackoverflow.com/a/2220476/1007926 )로 추가 할 수 있지만 어떤 구문 분석 된 문자가 잘 렸는지 확인하는 방법을 모릅니다. 감사!
Peter Becich

1
@JochemKuijpers "허용되는 답변이 특정 문제에 더 가깝게 일치 한다 "는 데 동의하지 않습니다 . OP는 " 유니 코드 번호를 알고 있다면 어떻게 기호를 구성 할 수 있습니까?"라고 명시 적으로 물었습니다. , "유니 코드 번호" 가 BMP 외부에 있으면 수락 된 답변이 작동하지 않습니다 . 예를 들어, SMP에 있기 때문에 유효한 코드 포인트 0x1040C에 대해 수락 된 응답이 실패합니다. 잘못된 답변이므로 수정하거나 삭제해야합니다.
skomisa

@skomisa OP 시나리오는 16 진수 유니 코드 이스케이프 시퀀스의 표현으로 제한됩니다. 서로 게이트 쌍으로 인코딩해야하는 문자가있는 경우이 이스케이프 시퀀스에 반영되므로 결국에는 여전히 작동합니다. 내가 말했듯이 이것은 더 일반적인 해결책이며 이것을 사용해야합니다.
Jochem Kuijpers dec

20

여기의 다른 답변은 U + FFFF (하나의 char 인스턴스를 다루는 답변)까지의 유니 코드 만 지원하거나 실제 기호 (Character.toChars ()에서 멈추는 답변 또는 잘못된 방법 사용)를 얻는 방법을 알려주지 않습니다. 그 후), 여기에 내 대답도 추가하십시오.

추가 코드 포인트도 지원하려면 다음을 수행해야합니다.

// this character:
// http://www.isthisthingon.org/unicode/index.php?page=1F&subpage=4&glyph=1F495
// using code points here, not U+n notation
// for equivalence with U+n, below would be 0xnnnn
int codePoint = 128149;
// converting to char[] pair
char[] charPair = Character.toChars(codePoint);
// and to String, containing the character we want
String symbol = new String(charPair);

// we now have str with the desired character as the first item
// confirm that we indeed have character with code point 128149
System.out.println("First code point: " + symbol.codePointAt(0));

또한 어떤 변환 방법이 작동하고 작동하지 않는지에 대한 빠른 테스트를 수행했습니다.

int codePoint = 128149;
char[] charPair = Character.toChars(codePoint);

String str = new String(charPair, 0, 2);
System.out.println("First code point: " + str.codePointAt(0));    // 128149, worked
String str2 = charPair.toString();
System.out.println("Second code point: " + str2.codePointAt(0));  // 91, didn't work
String str3 = new String(charPair);
System.out.println("Third code point: " + str3.codePointAt(0));   // 128149, worked
String str4 = String.valueOf(codePoint);
System.out.println("Fourth code point: " + str4.codePointAt(0));  // 49, didn't work
String str5 = new String(new int[] {codePoint}, 0, 1);
System.out.println("Fifth code point: " + str5.codePointAt(0));   // 128149, worked

한 줄로 작동하지 않는 이유는 무엇입니까? new String(Character.toChars(121849));Eclipse 콘솔에서 중단되지만 3 줄 버전이 작동합니다.
Noumenon

@Noumenon은 문제를 재현 할 수 없으며 나에게도 똑같이 잘 작동합니다
eis

더 나아가는 것에 대한 명성. 을 위해 str4할당 안 codecodePoint대신?
skomisa

6

그 기억 char일체형이며, 따라서 정수 값뿐만 아니라 문자 상수를들 수있다.

char c = 0x2202;//aka 8706 in decimal. \u codepoints are in hex.
String s = String.valueOf(c);

그것은 나에게 사각형 상자를주는 것입니다, ࢚. 나에게 "∂"를주지 않습니다.
Paul Reiners 2011

3
2202는 int당신이 찾고 있던 것이 아니기 때문 입니다. 0x2202를 찾고있었습니다. 내 잘못. 어떤 경우 든 int찾고있는 코드 포인트가 있으면으로 캐스트 char하고 사용할 수 있습니다 ( String원하는 경우 생성 ).
ILMTitan 2011

6

이것은 나를 위해 잘 작동했습니다.

  String cc2 = "2202";
  String text2 = String.valueOf(Character.toChars(Integer.parseInt(cc2, 16)));

이제 text2는 ∂를 가질 것입니다.


4
String st="2202";
int cp=Integer.parseInt(st,16);// it convert st into hex number.
char c[]=Character.toChars(cp);
System.out.println(c);// its display the character corresponding to '\u2202'.

1
이 게시물이 질문에 답할 수 있지만 수행중인 작업에 대한 설명이 필요합니다. 답변의 품질과 가독성을 향상시키기 위해
Ajil O.

1
감사합니다. 정말 도움이되었습니다! 잘 작동하고 여기에서 다른 솔루션보다 쉽습니다 (실제로 Java 사람들은 일을 너무 복잡하게 만드는 것을 좋아합니다).
parsecer 19

2

방법은 다음과 같습니다.

int cc = 0x2202;
char ccc = (char) Integer.parseInt(String.valueOf(cc), 16);
final String text = String.valueOf(ccc);

이 솔루션 은 Arne Vajhøj입니다.


이것이 효과가 있다는 말입니까? 그렇다면, 이것은 2 천, 2 백, 2를 0x2202로 재 해석하고 있기 때문에 작동합니다. 물론 전혀 같은 것이 아닙니다.
dty

4
오, 안돼! 유니 코드 값 (Java 소스의 \ u 이스케이프 시퀀스)은 16 진수입니다! 그래서 이것은 옳습니다. 라고 말함으로써 모든 사람을 오도했습니다 int c = 2202. 이것보다 더 나은 해결책 int c = 0x2202은 문자열 등을 통해 당신을 구할 것이라고 말하기
쉽습니다

3
+1 @dty : 중간 char ccc...선에 대한 전화는 전혀 없습니다 . 그냥 사용하는 int cc = 0x2202;다음과final String text=String.valueOf(cc);
앤드류 Coonce

2

이것은 오래된 질문이지만 오늘 릴리스 된 Java 11에서이를 수행하는 매우 쉬운 방법이 있습니다. Character.toString ()의 새로운 오버로드를 사용할 수 있습니다 .

public static String toString​(int codePoint)

Returns a String object representing the specified character (Unicode code point). The result is a string of length 1 or 2, consisting solely of the specified codePoint.

Parameters:
codePoint - the codePoint to be converted

Returns:
the string representation of the specified codePoint

Throws:
IllegalArgumentException - if the specified codePoint is not a valid Unicode code point.

Since:
11

이 메서드는 모든 유니 코드 코드 포인트를 지원하기 때문에 반환 된 문자열의 길이가 반드시 1 일 필요는 없습니다.

질문에 제공된 예제에 필요한 코드는 간단합니다.

    int codePoint = '\u2202';
    String s = Character.toString(codePoint); // <<< Requires JDK 11 !!!
    System.out.println(s); // Prints ∂

이 접근 방식은 다음과 같은 몇 가지 이점을 제공합니다.

  • .NET Framework를 사용하여 처리 할 수있는 코드 포인트가 아닌 모든 유니 코드 코드 포인트에서 작동합니다 char.
  • 간결하고 코드가 수행하는 작업을 이해하기 쉽습니다.
  • 값을 대신 원하는 문자열로 반환합니다 char[]. McDowell게시 한 답변은 코드 포인트를 char[].

이 답변에 대한 추가 설명으로 codePoint 변수를 만드는 방법이 즉시 분명해졌습니다. 구문은 int codePoint = 0x2202;다음과 같아야합니다. 그렇다면 : String s = Character.toString(codePoint); // <<< Requires JDK 11 !!! 또는 한 System.out.println(Character.toString(0x2202)); // Prints ∂
줄로 :

1

아래 코드는 일본어로 "be"라는 단어에 대해 4 개의 유니 코드 문자 (소수점으로 표시됨)를 작성합니다. 네, 일본어 동사 "be"는 4 자입니다! 문자의 값은 10 진수이며 예를 들어 split을 사용하여 String []의 배열로 읽혀졌습니다. Octal 또는 Hex가 있으면 parseInt도 기수를 사용합니다.

// pseudo code
// 1. init the String[] containing the 4 unicodes in decima :: intsInStrs 
// 2. allocate the proper number of character pairs :: c2s
// 3. Using Integer.parseInt (... with radix or not) get the right int value
// 4. place it in the correct location of in the array of character pairs
// 5. convert c2s[] to String
// 6. print 

String[] intsInStrs = {"12354", "12426", "12414", "12377"}; // 1.
char [] c2s = new char [intsInStrs.length * 2];  // 2.  two chars per unicode

int ii = 0;
for (String intString : intsInStrs) {
    // 3. NB ii*2 because the 16 bit value of Unicode is written in 2 chars
    Character.toChars(Integer.parseInt(intsInStrs[ii]), c2s, ii * 2 ); // 3 + 4
    ++ii; // advance to the next char
}

String symbols = new String(c2s);  // 5.
System.out.println("\nLooooonger code point: " + symbols); // 6.
// I tested it in Eclipse and Java 7 and it works.  Enjoy

1

여기 사이에 유니 코드 문자를 인쇄하는 블록 \u00c0으로는 \u00ff:

char[] ca = {'\u00c0'};
for (int i = 0; i < 4; i++) {
    for (int j = 0; j < 16; j++) {
        String sc = new String(ca);
        System.out.print(sc + " ");
        ca[0]++;
    }
    System.out.println();
}

0

불행하게도 첫 번째 주석 (newbiedoodle)에서 언급 한 반발 하나를 제거하는 것은 좋은 결과로 이어지지 않습니다. 대부분 (전부는 아님) IDE에서 구문 오류가 발생합니다. 그 이유는 Java 이스케이프 된 유니 코드 형식이 "\ uXXXX"구문을 예상하기 때문입니다. 여기서 XXXX는 4 개의 16 진수이며 필수입니다. 이 문자열을 조각에서 접 으려는 시도는 실패합니다. 물론 "\ u"는 "\\ u"와는 다릅니다. 첫 번째 구문은 이스케이프 된 'u'를 의미하고 두 번째는 이스케이프 된 백래시 (백래시) 다음에 'u'를 의미합니다. 아파치 페이지에이 동작을 정확히 수행하는 유틸리티가 있다는 것은 이상합니다. 그러나 실제로는 Escape mimic utility 입니다. Apache에는 몇 가지 자체 유틸리티가 있습니다 (테스트하지는 않았습니다). 당신이 원하는 것은 여전히 ​​아닐 수도 있습니다.그러나이 유틸리티 1 에는 솔루션에 대한 좋은 접근 방식이 있습니다. 위에서 설명한 조합 (MeraNaamJoker). 내 솔루션은이 이스케이프 된 모방 문자열을 만든 다음 다시 유니 코드로 변환합니다 (실제 이스케이프 된 유니 코드 제한을 피하기 위해). 텍스트 복사에 사용했기 때문에 uencode 방식에서는 '\\\\ u'를 제외하고 '\\ u'를 사용하는 것이 더 낫습니다. 시도 해봐.

  /**
   * Converts character to the mimic unicode format i.e. '\\u0020'.
   * 
   * This format is the Java source code format.
   * 
   *   CharUtils.unicodeEscaped(' ') = "\\u0020"
   *   CharUtils.unicodeEscaped('A') = "\\u0041"
   * 
   * @param ch  the character to convert
   * @return is in the mimic of escaped unicode string, 
   */
  public static String unicodeEscaped(char ch) {
    String returnStr;
    //String uniTemplate = "\u0000";
    final static String charEsc = "\\u";

    if (ch < 0x10) {
      returnStr = "000" + Integer.toHexString(ch);
    }
    else if (ch < 0x100) {
      returnStr = "00" + Integer.toHexString(ch);
    }
    else if (ch < 0x1000) {
      returnStr = "0" + Integer.toHexString(ch);
    }
    else
      returnStr = "" + Integer.toHexString(ch);

    return charEsc + returnStr;
  }

  /**
   * Converts the string from UTF8 to mimic unicode format i.e. '\\u0020'.
   * notice: i cannot use real unicode format, because this is immediately translated
   * to the character in time of compiling and editor (i.e. netbeans) checking it
   * instead reaal unicode format i.e. '\u0020' i using mimic unicode format '\\u0020'
   * as a string, but it doesn't gives the same results, of course
   * 
   * This format is the Java source code format.
   * 
   *   CharUtils.unicodeEscaped(' ') = "\\u0020"
   *   CharUtils.unicodeEscaped('A') = "\\u0041"
   * 
   * @param String - nationalString in the UTF8 string to convert
   * @return is the string in JAVA unicode mimic escaped
   */
  public String encodeStr(String nationalString) throws UnsupportedEncodingException {
    String convertedString = "";

    for (int i = 0; i < nationalString.length(); i++) {
      Character chs = nationalString.charAt(i);
      convertedString += unicodeEscaped(chs);
    }
    return convertedString;
  }

  /**
   * Converts the string from mimic unicode format i.e. '\\u0020' back to UTF8.
   * 
   * This format is the Java source code format.
   * 
   *   CharUtils.unicodeEscaped(' ') = "\\u0020"
   *   CharUtils.unicodeEscaped('A') = "\\u0041"
   * 
   * @param String - nationalString in the JAVA unicode mimic escaped
   * @return is the string in UTF8 string
   */
  public String uencodeStr(String escapedString) throws UnsupportedEncodingException {
    String convertedString = "";

    String[] arrStr = escapedString.split("\\\\u");
    String str, istr;
    for (int i = 1; i < arrStr.length; i++) {
      str = arrStr[i];
      if (!str.isEmpty()) {
        Integer iI = Integer.parseInt(str, 16);
        char[] chaCha = Character.toChars(iI);
        convertedString += String.valueOf(chaCha);
      }
    }
    return convertedString;
  }


-7

(답은 DOT NET 4.5에 있고 자바에서도 비슷한 접근 방식이 있어야합니다)

저는 인도 서부 벵골 출신입니다. 내가 당신의 문제를 이해했듯이 ... 당신은 유니 코드 HEX가있는 'অ'(벵골어로 된 문자)와 비슷한 것을 만들고 싶습니다.0X0985 .

이제 당신이 당신의 언어와 관련하여이 값을 안다면, 어떻게 그 언어 특정 유니 코드 기호를 맞출 것인가?

Dot Net에서는 다음과 같이 간단합니다.

int c = 0X0985;
string x = Char.ConvertFromUtf32(c);

이제 x가 답입니다. 그러나 이것은 HEX 변환에 의한 HEX이고 문장에서 문장으로 변환하는 것은 연구자들을위한 작업입니다 : P


질문은 실제로 자바입니다. .NET 답변이 여기에 어떻게 관련되어 있는지 모르겠습니다.
eis jul.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.