Membuat karakter Unicode dari nomornya


114

Saya ingin menampilkan karakter Unicode di Java. Jika saya melakukan ini, itu berfungsi dengan baik:

String symbol = "\u2202";

simbol sama dengan "∂". Itu yang saya mau.

Masalahnya adalah saya mengetahui nomor Unicode dan perlu membuat simbol Unicode darinya. Saya mencoba (kepada saya) hal yang jelas:

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

Namun, dalam kasus ini, simbol sama dengan "\ u2202". Bukan itu yang saya inginkan.

Bagaimana saya dapat membuat simbol jika saya mengetahui nomor Unicode-nya (tetapi hanya pada saat run-time --- saya tidak dapat membuat kode keras seperti contoh pertama)?


1
Hapus garis miring terbalik pertama, sehingga alih-alih keluar dari garis miring terbalik itu lolos dari urutan Unicode. Menggunakan "\\" memberi tahu Java bahwa Anda ingin mencetak "\", tidak menggunakannya sebagai urutan escape untuk karakter Unicode. Jika Anda menghapus yang pertama maka itu akan keluar dari urutan Unicode dan bukan garis miring terbalik kedua. Setidaknya, itu akan menjadi yang terbaik dari pengetahuan saya.
Gugatan Dana Monica

Jawaban:


73

Transmisikan intke file char. Anda dapat mengubahnya menjadi Stringpenggunaan Character.toString():

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

EDIT:

Ingatlah bahwa urutan escape dalam kode sumber Java ( \ubit) ada di HEX, jadi jika Anda mencoba mereproduksi urutan escape, Anda memerlukan sesuatu seperti int c = 0x2202.


3
Itu hanya memberi saya kotak persegi, ࢚. Itu tidak memberi saya "∂".
Paul Reiners

19
Bahaya, Akankah Robinson! Jangan lupa bahwa poin kode Unicode belum tentu cocok dengan karakter . Jadi, Anda harus benar-benar yakin sebelumnya bahwa nilai Anda clebih kecil dari 0x10000, atau pendekatan ini akan rusak parah.
David Diberikan

1
@NickHartley Maaf, jangan ikuti --- apakah Anda salah membaca 0x10000 untuk 10000?
David Diberikan

10
Itu sebabnya saya berkata 'di bawah'! Dan saya perlu menekankan bahwa, meskipun fakta bahwa karakter Java hanya naik ke 0xffff, poin kode Unicode naik ke 0xfffff. Standar Unicode diubah setelah Java dirancang. Saat ini karakter Java secara teknis menampung kata-kata UTF-16, bukan poin kode Unicode, dan melupakan ini akan menyebabkan kerusakan yang mengerikan saat aplikasi Anda menemukan skrip eksotis.
David Diberikan

3
@Dvid Terima kasih untuk Java chars go up to 0xFFFF. Saya tidak tahu hal itu.
Tony Ennis

128

Jika Anda ingin mendapatkan unit kode berenkode UTF-16 sebagai char, Anda dapat mengurai integer dan mentransmisikannya seperti yang disarankan orang lain.

Jika Anda ingin mendukung semua poin kode, gunakan Character.toChars(int). Ini akan menangani kasus di mana titik kode tidak dapat dimasukkan dalam satu charnilai.

Doc mengatakan:

Mengonversi karakter yang ditentukan (titik kode Unicode) ke representasi UTF-16 yang disimpan dalam larik karakter. Jika titik kode yang ditentukan adalah nilai BMP (Basic Multilingual Plane atau Plane 0), array karakter yang dihasilkan memiliki nilai yang sama dengan codePoint. Jika titik kode yang ditentukan adalah titik kode tambahan, larik karakter yang dihasilkan memiliki pasangan pengganti yang sesuai.


Meskipun ini adalah solusi yang lebih umum dan dalam banyak kasus Anda harus menggunakan ini di atas jawaban yang diterima, jawaban yang diterima lebih cocok dengan masalah spesifik yang diminta Paulus.
Jochem Kuijpers

2
Pertama, terima kasih! Di Scala, saya masih tidak dapat mengurai karakter yang lebih besar dari a char. scala> "👨‍🎨".map(_.toInt).flatMap((i: Int) => Character.toChars(i)).map(_.toHexString)memberikan res11: scala.collection.immutable.IndexedSeq[String] = Vector(f468, 200d, f3a8) emoji ini, "penyanyi pria", dialamatkan dengan tiga poin kode U+1f468, U+200ddan U+1f3a8. Angka paling signifikan hilang. Saya dapat menambahkannya dengan bitwise ATAU ( stackoverflow.com/a/2220476/1007926 ), tetapi tidak tahu cara menentukan karakter parsing mana yang telah terpotong. Terima kasih!
Peter Becich

1
@JochemKuijpers Saya tidak setuju bahwa "jawaban yang diterima lebih mendekati masalah tertentu" . OP secara eksplisit bertanya "Bagaimana saya bisa membuat simbol jika saya tahu nomor Unicode-nya ...?" , dan jawaban yang diterima tidak dapat berfungsi jika "nomor Unicode" itu berada di luar BMP. Misalnya, jawaban yang diterima gagal untuk titik kode yang valid 0x1040C karena berada di SMP. Ini adalah jawaban yang buruk, dan harus diperbaiki atau dihapus.
skomisa

Skenario OP @skomisa terbatas pada representasi urutan escape Unicode heksadesimal. Jika Anda memiliki karakter yang harus dienkode sebagai pasangan pengganti, hal itu tercermin dalam urutan pelolosan ini, jadi masih berfungsi pada akhirnya. Seperti yang saya katakan, ini adalah solusi yang lebih umum dan Anda harus menggunakan ini.
Jochem Kuijpers

20

Jawaban lain di sini hanya mendukung unicode hingga U + FFFF (jawaban hanya berurusan dengan satu contoh char) atau tidak memberi tahu cara mendapatkan simbol sebenarnya (jawaban berhenti di Character.toChars () atau menggunakan metode yang salah setelah itu), jadi menambahkan jawaban saya di sini juga.

Untuk mendukung poin kode tambahan juga, inilah yang perlu dilakukan:

// 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));

Saya juga melakukan pengujian cepat tentang metode konversi mana yang berfungsi dan mana yang tidak

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

Kenapa tidak berfungsi sebagai satu baris? new String(Character.toChars(121849));istirahat di konsol Eclipse, tetapi versi tiga baris berfungsi.
Noumenon

@Noumenon tidak dapat mereproduksi masalah tersebut, berfungsi sama baiknya untuk saya
eis

Kudos untuk melangkah lebih jauh. Untuk str4tugas, tidak harus codemenjadi codePointbukan?
skomisa

6

Ingat itu charadalah tipe integral, dan dengan demikian dapat diberi nilai integer, serta konstanta char.

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

Itu hanya memberi saya kotak persegi, ࢚. Itu tidak memberi saya "∂".
Paul Reiners

3
Itu karena 2202 bukanlah yang intAnda cari. Anda sedang mencari 0x2202. Salahku. Bagaimanapun, jika Anda memiliki inttitik kode yang Anda cari, Anda dapat mentransmisikannya ke a char, dan menggunakannya (untuk membuat a Stringjika Anda mau).
ILMTitan

6

Yang ini bekerja dengan baik untuk saya.

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

Sekarang text2 akan memiliki ∂.


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
Meskipun posting ini mungkin menjawab pertanyaan tersebut, diperlukan penjelasan tentang apa yang Anda lakukan; untuk meningkatkan kualitas dan keterbacaan jawaban Anda
Ajil O.

1
Terima kasih, itu sangat membantu saya! Bekerja dengan baik dan lebih mudah daripada solusi lain di sini (sungguh, orang Java sangat suka hal-hal yang terlalu rumit).
parsecer

2

Beginilah cara Anda melakukannya:

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

Solusi ini dibuat oleh Arne Vajhøj.


Apakah Anda mengatakan ini berhasil? Jika demikian, ini berfungsi karena Anda menafsirkan ulang dua ribu, dua ratus dua sebagai 0x2202, yang, tentu saja, bukanlah hal yang sama sama sekali.
dty

4
Oh, tidak, tunggu! Nilai Unicode (urutan pelolosan \ u di sumber Java) ADALAH hex! Jadi ini benar. Anda baru saja menyesatkan semua orang dengan mengatakan int c = 2202, mana yang salah! Solusi yang lebih baik daripada ini adalah mudah untuk mengatakan int c = 0x2202yang akan menyelamatkan Anda melalui String, dll.
dty

3
+1 @dty: Sama sekali tidak ada panggilan untuk char ccc...garis tengah . Cukup gunakan int cc = 0x2202;dan kemudianfinal String text=String.valueOf(cc);
Andrew Coonce

2

Meskipun ini adalah pertanyaan lama, ada cara yang sangat mudah untuk melakukannya di Java 11 yang dirilis hari ini: Anda dapat menggunakan kelebihan baru dari 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

Karena metode ini mendukung titik kode Unicode apa pun, panjang String yang dikembalikan tidak harus 1.

Kode yang dibutuhkan untuk contoh yang diberikan dalam pertanyaan adalah:

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

Pendekatan ini menawarkan beberapa keuntungan:

  • Ini berfungsi untuk titik kode Unicode apa pun daripada hanya yang dapat ditangani menggunakan file char.
  • Singkat, dan mudah untuk memahami apa yang dilakukan kode tersebut.
  • Ini mengembalikan nilai sebagai string daripada a char[], yang sering kali Anda inginkan. Jawaban yang diposting oleh McDowell sesuai jika Anda ingin titik kode dikembalikan sebagai char[].

Beberapa klarifikasi tambahan untuk yang satu ini karena jawaban ini segera menjelaskan kepada saya cara membuat variabel codePoint. Sintaksnya di sini seharusnya: int codePoint = 0x2202;Kemudian: String s = Character.toString(codePoint); // <<< Requires JDK 11 !!! Atau dalam satu baris: System.out.println(Character.toString(0x2202)); // Prints ∂ Semoga ini membantu orang lain menggunakan fitur JDK 11 ini.
Loathian

1

Kode di bawah ini akan menulis 4 karakter unicode (diwakili oleh desimal) untuk kata "be" dalam bahasa Jepang. Ya, kata kerja "be" dalam bahasa Jepang memiliki 4 karakter! Nilai karakter dalam desimal dan telah dibaca ke dalam array String [] - menggunakan split misalnya. Jika Anda memiliki Oktal atau Hex, parseInt juga mengambil radix.

// 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

Berikut ini adalah blok untuk mencetak karakter unicode antara \u00c0ke \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

Sayangnya, menghilangkan satu serangan balik seperti yang disebutkan pada komentar pertama (newbiedoodle) tidak membawa hasil yang baik. Sebagian besar (jika tidak semua) IDE mengeluarkan kesalahan sintaksis. Alasannya adalah karena format Java Escaped Unicode mengharapkan sintaks "\ uXXXX", di mana XXXX adalah 4 digit heksadesimal, yang wajib diisi. Upaya untuk melipat string ini dari potongan-potongan gagal. Tentu saja, "\ u" tidak sama dengan "\\ u". Sintaks pertama berarti lolos 'u', kedua berarti lolos backlash (yang merupakan backlash) diikuti oleh 'u'. Aneh, bahwa pada halaman Apache disajikan utilitas, yang melakukan perilaku ini. Namun pada kenyataannya, itu adalah utilitas meniru Escape . Apache memiliki beberapa utilitasnya sendiri (saya tidak mengujinya), yang melakukan ini untuk Anda. Mungkin, bukan itu yang ingin Anda miliki.Tetapi utilitas ini 1 memiliki pendekatan solusi yang baik. Dengan kombinasi yang dijelaskan di atas (MeraNaamJoker). Solusi saya adalah membuat string mimik yang lolos ini dan kemudian mengubahnya kembali menjadi unicode (untuk menghindari pembatasan Unicode yang lolos nyata). Saya menggunakannya untuk menyalin teks, jadi mungkin saja dalam metode uencode akan lebih baik menggunakan '\\ u' kecuali '\\\\ u'. Cobalah.

  /**
   * 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

(JAWABAN DI DOT NET 4.5 dan di java, harus ada pendekatan serupa)

Saya dari West Bengal di INDIA. Seperti yang saya mengerti masalah Anda adalah ... Anda ingin menghasilkan mirip dengan 'অ' (Ini adalah surat dalam bahasa Bengali) yang memiliki Unicode HEX: 0X0985.

Sekarang jika Anda mengetahui nilai ini sehubungan dengan bahasa Anda, lalu bagaimana Anda akan menghasilkan simbol Unicode khusus bahasa itu, bukan?

Di Dot Net sesederhana ini:

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

Sekarang x adalah jawabanmu. Tetapi ini adalah konversi HEX oleh HEX dan konversi kalimat ke kalimat adalah pekerjaan bagi peneliti: P


pertanyaannya memang untuk java. Saya tidak melihat bagaimana jawaban NET terkait di sini.
eis
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.