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


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+200d와 U+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할당 안 code될 codePoint대신?
— 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.