Numarasından Unicode karakteri oluşturma


114

Java'da bir Unicode karakteri görüntülemek istiyorum. Bunu yaparsam gayet iyi çalışıyor:

String symbol = "\u2202";

sembolü "∂" ye eşittir. İstediğim şey bu.

Sorun şu ki, Unicode numarasını bilmem ve bundan Unicode sembolünü yaratmam gerekiyor. (Bana) apaçık olan şeyi denedim:

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

Ancak bu durumda sembol "\ u2202" ye eşittir. İstediğim bu değil.

Unicode numarasını biliyorsam sembolü nasıl oluşturabilirim (ancak yalnızca çalışma zamanında --- ilk örnekteki gibi sabit kodlayamıyorum)?


1
İlk ters eğik çizgiyi kaldırın, böylece ters eğik çizgiden kaçmak yerine Unicode dizisinden kaçar. "\\" kullanılması Java'ya "\" yazdırmak istediğinizi söyler, bunu Unicode karakterleri için bir çıkış dizisinin geçmişi olarak kullanmaz. İlkini kaldırırsanız, ikinci ters eğik çizgiden değil, Unicode dizisinden kaçacaktır. En azından, bildiğim kadarıyla olacak.
Fund Monica'nın Davası

Yanıtlar:


73

Sadece intbir char. Bir o dönüştürebilirsiniz Stringkullanarak Character.toString():

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

DÜZENLE:

Java kaynak kodundaki ( \ubitler) kaçış dizilerinin HEX'te olduğunu unutmayın, bu nedenle bir kaçış dizisini yeniden oluşturmaya çalışıyorsanız, buna benzer bir şeye ihtiyacınız olacak int c = 0x2202.


3
Bu bana sadece kare bir kutu veriyor, ࢚. Bana "∂" vermiyor.
Paul Reiners

19
Tehlike, Will Robinson! Unicode kod noktalarının bir karaktere sığmayacağını unutmayın . Bu nedenle, değerinizin c0x10000'den küçük olduğundan kesinlikle emin olmalısınız , aksi takdirde bu yaklaşım korkunç bir şekilde bozulacaktır.
David

1
@NickHartley Pardon, takip etmeyin --- 0x10000'ü 10000 için yanlış mı okudunuz?
David

10
Bu yüzden 'aşağıda' dedim! Java karakterlerinin yalnızca 0xffff'a kadar çıkmasına rağmen Unicode kod noktalarının 0xfffff'a kadar çıktığını vurgulamalıyım. Java tasarlandıktan sonra Unicode standardı değişti. Bugünlerde Java karakterleri teknik olarak UTF-16 kelimelerini tutuyor, Unicode kod noktalarını değil ve bunu unutmak, uygulamanız egzotik bir komut dosyasıyla karşılaştığında korkunç kırılmalara neden olacaktır.
David

3
@ DavidGiven için teşekkürler Java chars go up to 0xFFFF. Bunu bilmiyordum.
Tony Ennis

128

UTF-16 kodlu bir kod birimini bir olarak almak charistiyorsanız, tamsayıyı ayrıştırabilir ve diğerlerinin önerdiği gibi ona çevirebilirsiniz.

Tüm kod noktalarını desteklemek istiyorsanız kullanın Character.toChars(int). Bu, kod noktalarının tek bir chardeğere sığamadığı durumları ele alır .

Doc diyor:

Belirtilen karakteri (Unicode kod noktası) bir char dizisinde depolanan UTF-16 gösterimine dönüştürür. Belirtilen kod noktası bir BMP (Temel Çok Dilli Düzlem veya Düzlem 0) değeriyse, ortaya çıkan char dizisi, codePoint ile aynı değere sahiptir. Belirtilen kod noktası tamamlayıcı bir kod noktasıysa, ortaya çıkan karakter dizisi karşılık gelen vekil çiftine sahiptir.


Bu daha genel bir çözüm olsa da ve çoğu durumda bunu kabul edilen yanıt yerine kullanmanız gerekirken, kabul edilen yanıt Paul'ün istediği belirli soruna daha yakın bir eşleşme olacaktır.
Jochem Kuijpers

2
Öncelikle teşekkürler! Scala'da, a'dan daha büyük karakterleri hala ayrıştıramıyorum char. scala> "👨‍🎨".map(_.toInt).flatMap((i: Int) => Character.toChars(i)).map(_.toHexString)verir res11: scala.collection.immutable.IndexedSeq[String] = Vector(f468, 200d, f3a8) üç kod puanla ele alınmaktadır Bu emoji, "erkek şarkıcı", U+1f468, U+200dve U+1f3a8. En önemli rakam eksik. Bitsel OR ( stackoverflow.com/a/2220476/1007926 ) ile ekleyebilirim , ancak hangi ayrıştırılmış karakterlerin kesildiğini nasıl belirleyeceğimi bilmiyorum. Teşekkürler!
Peter Becich

1
@JochemKuijpers "Kabul edilen cevabın belirli bir soruna daha yakın bir eşleşme" olduğunu kabul etmiyorum . OP açıkça sordum "Nasıl sembolü oluşturabilirsiniz Ben onun Unicode numarasını biliyorsanız ...?" ve bu "Unicode numarası" BMP'nin dışındaysa kabul edilen yanıt çalışamaz . Örneğin, kabul edilen yanıt, SMP'de olduğu için geçerli kod noktası 0x1040C için başarısız olur. Kötü bir yanıttır ve düzeltilmesi veya silinmesi gerekir.
skomisa

@skomisa OPs senaryosu onaltılık Unicode kaçış dizisinin gösterimi ile sınırlıdır. Vekil çift olarak kodlanması gereken bir karakteriniz varsa, bu kaçış dizilerine yansıtılır, bu yüzden sonunda hala çalışır. Dediğim gibi bu daha genel bir çözüm ve bunu kullanmalısınız.
Jochem Kuijpers

20

Buradaki diğer cevaplar ya U + FFFF'ye kadar (sadece bir char örneğiyle ilgili cevaplar) unicode'u destekliyor ya da gerçek sembole nasıl ulaşılacağını söylemiyor (cevaplar Character.toChars () konumunda duruyor ya da yanlış yöntem kullanıyor ondan sonra), cevabımı da buraya ekledim.

Ek kod noktalarını da desteklemek için yapılması gereken şudur:

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

Ayrıca hangi dönüştürme yöntemlerinin işe yarayıp hangilerinin yaramadığına dair hızlı bir test yaptım

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

Neden tek astar olarak çalışmıyor? new String(Character.toChars(121849));Eclipse konsolunda kırılıyor, ancak üç satırlı sürüm çalışıyor.
Noumenon

@Noumenon sorunu yeniden oluşturamıyor, benim için eşit derecede iyi çalışıyor
eis

Daha ileri gittiğiniz için tebrikler. İçin str4atama, olmamalıdır codeolmak codePointyerine?
skomisa

6

Bunun charbir integral türü olduğunu ve bu nedenle bir tamsayı değerinin yanı sıra bir karakter sabitinin de verilebileceğini unutmayın.

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

Bu bana sadece kare bir kutu veriyor, ࢚. Bana "∂" vermiyor.
Paul Reiners

3
Bunun nedeni 2202'nin intaradığınız kişi olmamasıdır . 0x2202'yi arıyordunuz. Benim hatam. Her durumda, intaradığınız kod noktasına sahipseniz, onu sadece a'ya çevirebilir charve kullanabilirsiniz ( Stringisterseniz bir oluşturmak için).
ILMTitan

6

Bu benim için iyi çalıştı.

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

Şimdi metin2'de ∂ olacak.


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
Bu gönderi soruyu yanıtlasa da, ne yaptığınızla ilgili bir açıklama gerekiyor; cevabınızın kalitesini ve okunabilirliğini artırmak için
Ajil O.

1
Teşekkürler, bana gerçekten yardımcı oldu! İyi çalışıyor ve buradaki diğer çözümlerden daha kolay (gerçekten, Java insanları işleri aşırı karmaşık hale getirmekten hoşlanıyor).
parsecer

2

Bunu nasıl yapıyorsun:

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

Bu çözüm Arne Vajhøj tarafından.


Bunun işe yaradığını mı söylüyorsun? Eğer öyleyse, bu işe yarar çünkü iki bin, iki yüz ve ikiyi 0x2202 olarak yeniden yorumluyorsunuz, ki bu tabii ki aynı şey değil.
dty

4
Oh, hayır, dayan! Unicode değerleri (Java kaynağındaki \ u kaçış dizileri) onaltılıktır! Yani bu doğru. int c = 2202Yanlış olanı söyleyerek herkesi kandırdın ! Bundan daha iyi bir çözümün, int c = 0x2202bir String vb.
İle

3
+1 @dty: Orta char ccc...hatta kesinlikle bir çağrı yok . Sadece kullan int cc = 0x2202;ve sonrafinal String text=String.valueOf(cc);
Andrew Coonce

2

Bu eski bir soru olsa da, bugün yayınlanan Java 11'de bunu yapmanın çok kolay bir yolu var: Character.toString () 'nin yeni bir aşırı yüklemesini kullanabilirsiniz :

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

Bu yöntem herhangi bir Unicode kod noktasını desteklediğinden, döndürülen String'in uzunluğu mutlaka 1 değildir.

Soruda verilen örnek için gereken kod basitçe:

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

Bu yaklaşım birkaç avantaj sunar:

  • Yalnızca bir .NET Framework kullanılarak ele alınabilenler yerine herhangi bir Unicode kod noktası için çalışır char.
  • Kısa ve öz ve kodun ne yaptığını anlamak kolaydır.
  • Değeri a yerine bir dize olarak döndürür char[], bu genellikle istediğiniz şeydir. McDowell tarafından gönderilen cevap , kod noktasının olarak döndürülmesini istiyorsanız uygundur char[].

Bu yanıtla ilgili bazı ek açıklamalar, bu yanıt bana codePoint değişkeninin nasıl oluşturulacağını hemen açık hale getirdi. Buradaki sözdizimi şöyle olmalıdır: int codePoint = 0x2202;O zaman: String s = Character.toString(codePoint); // <<< Requires JDK 11 !!! Veya tek System.out.println(Character.toString(0x2202)); // Prints ∂
satırda

1

Aşağıdaki kod, Japonca "be" kelimesi için 4 unicode karakter (ondalık sayılarla temsil edilir) yazacaktır. Evet, Japoncada "be" fiilinin 4 karakteri var! Karakterlerin değeri ondalıktır ve bir String [] dizisine okunmuştur - örneğin bölme kullanılarak. Octal veya Hex'iniz varsa, parseInt de bir radix alın.

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

İşte arasındaki unicode karakter yazdırmak için bir bloktur \u00c0için \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

Ne yazık ki, ilk yorumda (newbiedoodle) belirtildiği gibi bir tepkiyi kaldırmak iyi bir sonuca yol açmaz. Çoğu (tümü değilse) IDE sözdizimi hatası verir. Bunun nedeni, Java Çıkışlı Unicode biçiminin "\ uXXXX" sözdizimini beklemesidir; burada XXXX, zorunlu olan 4 onaltılık basamaktır. Bu ipi parçalardan katlama girişimleri başarısız olur. Elbette, "\ u", "\\ u" ile aynı değildir. İlk sözdizimi, kaçan "u" anlamına gelir; ikincisi, kaçan boşluk (geri tepme) ve ardından "u" anlamına gelir. Apache sayfalarında tam olarak bu davranışı yapan bir yardımcı program sunulması gariptir. Ama gerçekte, Escape taklit aracıdır . Apache'nin bazı yardımcı programları vardır (onları test etmedim), bunlar sizin için bu işi yapar. Belki, hala sahip olmak istediğin o değil.Ancak bu yardımcı program 1çözüme iyi bir yaklaşımınız var. Yukarıda açıklanan kombinasyonla (MeraNaamJoker). Benim çözümüm, bu Escaped mimik dizesini oluşturmak ve sonra onu tekrar unicode'a dönüştürmek (gerçek Kaçan Unicode kısıtlamasını önlemek için). Metni kopyalamak için kullandım, bu nedenle uencode yönteminde '\\\\ u' dışında '\\ u' kullanmak daha iyi olabilir. Dene.

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

(CEVAP DOT NET 4.5'DİR ve java'da benzer bir yaklaşım olması gerekir)

Hindistan'da Batı Bengal'denim. Anladığım kadarıyla probleminiz ... Unicode HEX: 'অ' ye benzer (Bengalce bir harftir) üretmek istiyorsunuz 0X0985.

Şimdi, bu değeri kendi dilinize göre biliyorsanız, o dile özgü Unicode sembolünü nasıl üreteceksiniz?

Dot Net'te bu kadar basit:

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

Şimdi cevabın x. Ancak bu, HEX'in HEX dönüştürmesidir ve cümle dönüştürme araştırmacılar için bir çalışmadır: P


soru gerçekten java içindir. NET yanıtının burada nasıl ilişkili olduğunu anlamıyorum.
eis
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.