その番号からUnicode文字を作成する


114

JavaでUnicode文字を表示したい。これを行うと、うまく動作します。

String symbol = "\u2202";

記号は「∂」と等しい。それが私が欲しいものです。

問題は、私がUnicode番号を知っていて、そこからUnicodeシンボルを作成する必要があることです。私は(私に)明白なことを試しました:

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

ただし、この場合、シンボルは "\ u2202"と等しくなります。それは私が望むものではありません。

Unicode番号がわかっている場合にシンボルを構築するにはどうすればよいですか(ただし、実行時のみ---最初の例のようにハードコードすることはできません)?


1
最初のバックスラッシュを削除して、バックスラッシュをエスケープする代わりにUnicodeシーケンスをエスケープします。「\\」を使用すると、Unicode文字のエスケープシーケンスの過去として使用するのではなく、「\」を出力するようにJavaに指示します。最初のものを削除すると、代わりに2番目のバックスラッシュではなくUnicodeシーケンスがエスケープされます。少なくとも、私の知る限りです。
モニカの訴訟に資金を提供

回答:


73

ちょうどあなたをキャストintしますchar。あなたはそれをString使ってに変換することができますCharacter.toString()

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

編集:

Javaソースコード(\uビット)のエスケープシーケンスはHEXであることを覚えておいてください。したがって、エスケープシーケンスを再現しようとする場合は、のようなものが必要になりますint c = 0x2202


3
それは私に四角い箱を与えているだけです、࢚。それは私に「not」を与えていません。
ポールライナー

19
危険、ウィル・ロビンソン!Unicodeコードポイントが必ずしもcharに収まるとは限らないことを忘れないでください。したがって、値がc0x10000より小さいことを事前に確実に確認しておく必要があります。そうしないと、このアプローチはひどく壊れてしまいます。
デビッドギブン

1
@NickHartley申し訳ありませんが、フォローしないでください--- 0x10000を10000と誤って読みましたか?
Davidが

10
だから私は「下」と言いました!また、Java文字は0xffffまでしか増加しないという事実にもかかわらず、Unicodeコードポイントは0xfffffまで増加することを強調する必要があります。Unicode規格は、Javaの設計後に変更されました。最近のJava文字は技術的にはUnicodeコードポイントではなくUTF-16ワードを保持しており、これを忘れると、アプリケーションがエキゾチックなスクリプトに遭遇したときに恐ろしい破損が発生します。
デビッド・ギブン

3
@DavidGivenに感謝しJava chars go up to 0xFFFFます。それは知らなかった。
Tony Ennis

128

UTF-16でエンコードされたコードユニットをとして取得したい場合はchar、整数を解析して、他の人が示唆しているようにキャストできます。

すべてのコードポイントをサポートする場合は、を使用しますCharacter.toChars(int)。これは、コードポイントが単一に収まらない場合を処理しますchar値にます。

ドクは言う:

指定された文字(Unicodeコードポイント)を、char配列に格納されているUTF-16表現に変換します。指定されたコードポイントがBMP(Basic Multilingual PlaneまたはPlane 0)値である場合、結果のchar配列はcodePointと同じ値になります。指定されたコードポイントが補足コードポイントである場合、結果のchar配列には対応するサロゲートペアがあります。


これはより一般的な解決策であり、多くの場合、これを承認済みの回答に対して使用する必要がありますが、承認済みの回答は、Paulが求めた特定の問題により近い一致です。
Jochem Kuijpers

2
まず、ありがとう!Scalaでは、まだより大きい文字を解析できませんcharscala> "👨‍🎨".map(_.toInt).flatMap((i: Int) => Character.toChars(i)).map(_.toHexString)Give res11: scala.collection.immutable.IndexedSeq[String] = Vector(f468, 200d, f3a8) この絵文字「男性歌手」は、3つのコードポイントU+1f468U+200dおよびで対処されますU+1f3a8。最上位桁が欠落しています。ビット単位のOR(stackoverflow.com/a/2220476/1007926)を使用して追加できますが、どの解析済み文字が切り捨てられたかを判別する方法がわかりません。ありがとう!
Peter Becich、2018年

1
@JochemKuijpers 「受け入れられた答えは特定の問題により近いものである」ということに同意しません。OPは、Unicode番号がわかっている場合にシンボルを作成するにはどうすればよいですか?」、その「Unicode番号」がBMPの外にある場合、受け入れられた回答は機能しません。たとえば、SMPにあるため、有効なコードポイント0x1040Cに対して受け入れられた回答は失敗します。これは悪い答えであり、修正または削除する必要があります。
skomisa

@skomisa OPシナリオは、16進数のUnicodeエスケープシーケンスの表現に限定されています。サロゲートペアとしてエンコードする必要がある文字がある場合、これらの文字はこれらのエスケープシーケンスに反映されるため、最終的には正しく機能します。私が言ったように、これはより一般的な解決策であり、これを使用する必要があります。
Jochem Kuijpers

20

ここでの他の回答は、U + FFFFまでのユニコード(charの1つのインスタンスのみを処理する回答)のみをサポートするか、実際のシンボルに到達する方法を伝えません(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 2016年

@Noumenonは問題を再現できず、同じように機能します
eis

さらに進んでいただきありがとうございます。str4割り当てについては、代わりにすべきではありませcodecodePointか?
skomisa

6

それは覚えているchar一体型であるので、整数値、ならびにチャー定数を与えることができます。

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

それは私に四角い箱を与えているだけです、࢚。それは私に「not」を与えていません。
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はhaveになります。


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の人々は物事を複雑にしすぎるのが好きです)。
パーサー

2

これがあなたのやり方です:

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

このソリューションは、ArneVajhøjによるものです。


これはうまくいくって言ってるの?もしそうなら、これは、2000、200、2を0x2202として再解釈しているので機能します。もちろん、これはまったく同じではありません。
DTY

4
ああ、いや、ちょっと待って!Unicode値(Javaソースの\ uエスケープシーケンス)は16進数です!これは正しいです。あなたint c = 2202はと言ってみんなを惑わしました、それは間違っています!これよりも優れた解決策はint c = 0x2202、文字列などを経由する
手間

3
+1 @dty:真ん中のchar ccc...線は絶対に必要ありません。そのまま使用int cc = 0x2202;してくださいfinal String text=String.valueOf(cc);
Andrew Coonce、2015年

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

このメソッドは任意のUnicodeコードポイントをサポートするため、返される文字列の長さは必ずしも1であるとは限りません。

質問の例に必要なコードは次のとおりです。

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

このアプローチには、いくつかの利点があります。

  • これは、を使用して処理できるものだけでなく、あらゆるUnicodeコードポイントで機能しますchar
  • それは簡潔で、コードが何をしているかを理解するのは簡単です。
  • char[]たいていの場合、値をとしてではなく文字列として返します。McDowell投稿した回答は、コードポイントをとして返したい場合に適していますchar[]

この回答は、codePoint変数を作成する方法を私にすぐに明らかにしたので、これに関するいくつかの追加の説明があります。ここでの構文は次のとおりです。int codePoint = 0x2202;次に:String s = Character.toString(codePoint); // <<< Requires JDK 11 !!! または1行で:System.out.println(Character.toString(0x2202)); // Prints ∂ これがJDK 11のこの機能を使用している他の人を助けることを願っています
Loathian

1

以下のコードは、日本語の「be」という単語の4つのUnicode文字(小数で表される)を書き込みます。はい、日本語の「be」という動詞は4文字です。文字の値は10進数で、String []の配列に読み込まれています-たとえば、splitを使用しています。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

toの間\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)で述べられているように1つのバックラッシュを削除しても、良い結果にはつながりません。IDEのほとんど(すべてではない)で構文エラーが発生します。その理由は、Java Escaped Unicode形式が構文 "\ uXXXX"を予期しているためです。ここで、XXXXは必須の4桁の16進数です。この文字列を断片から折り畳む試みは失敗します。もちろん、「\ u」は「\\ u」と同じではありません。最初の構文はエスケープされた 'u'を意味し、2番目の構文はエスケープされたバックラッシュ(バックラッシュ)の後に 'u'が続くことを意味します。奇妙なことに、Apacheページにユーティリティが表示され、この動作を正確に実行します。しかし、実際には、それはエスケープ模倣ユーティリティですがです。Apacheには独自のユーティリティがいくつかあります(私はそれらをテストしていません)。たぶん、それはまだそれではない、あなたが欲しいもの。、このユーティリティ1ソリューションへの良いアプローチを持っています。上記の組み合わせ(MeraNaamJoker)。私の解決策は、このエスケープされた模倣文字列を作成し、それをUnicodeに変換し直すことです(実際のエスケープされたUnicodeの制限を回避するため)。私はそれをテキストのコピーに使用したので、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とJavaにあり、同様のアプローチが存在する必要があります)

私はインドの西ベンガル出身です。あなたの問題は私が理解しているように... Unicode HEXを持つ 'অ'(これはベンガル語の文字です)に似たものを生成したいとします。0X0985

あなたがあなたの言語に関してこの値を知っているなら、あなたはその言語固有のUnicodeシンボルをどのように正しく生成しますか?

Dot Netでは、次のように簡単です。

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

ここでxが答えです。しかし、これはHEX変換によるHEXであり、文から文への変換は研究者の仕事です:P


質問は確かにJavaです。.NETの回答がここでどのように関連しているかはわかりません。
eis 2015
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.