110 votes

Comment puis-je parcourir les points de code Unicode d'une chaîne Java?

Donc, je sais à propos de String#codePointAt(int), mais c'est indexée par l' char offset, non pas par le codepoint décalage.

Je suis en train de réfléchir à essayer quelque chose comme:

  • à l'aide de String#charAt(int) pour obtenir le char à un indice
  • tester si l' char est dans le haut de gamme de substituts
    • si oui, utilisez String#codePointAt(int) pour obtenir le codepoint, et incrémenter l'index par 2
    • si non, utilisez le char de la valeur comme le codepoint, et incrémenter l'index par 1

Mais mes préoccupations sont

  • Je ne suis pas sûr de savoir si codepoints qui sont naturellement dans le haut de gamme de substituts seront stockées sous forme de deux char des valeurs ou un
  • cela semble être une terrible manière coûteuse pour itérer à travers des personnages
  • quelqu'un a dû trouver quelque chose de mieux.

152voto

Jonathan Feinberg Points 24791

Oui, Java utilise un codage UTF-16-esque pour les représentations internes de Strings et, oui, il code des caractères extérieurs au BMP à l'aide du schéma de substitution.

Si vous savez que vous aurez affaire à des caractères situés en dehors du BMP, voici la manière canonique de parcourir les caractères d'une chaîne Java:

 final int length = s.length();
for (int offset = 0; offset < length; ) {
   final int codepoint = s.codePointAt(offset);

   // do something with the codepoint

   offset += Character.charCount(codepoint);
}
 

8voto

rogerdpack Points 12806

Je pensais que j'ajouterais mon travail (inefficace, mais pratique) autour du style de wrapper (je ne suis pas sûr que les autres bibliothèques principales le fournissent, donnez-le carillon si c'est le cas):

  public static List<Integer> stringToCodePoints(String in) {
    List<Integer> out = new ArrayList<Integer>();
    final int length = in.length();
    for (int offset = 0; offset < length; ) {
      final int codepoint = in.codePointAt(offset);
      out.add(codepoint);
      offset += Character.charCount(codepoint);
    }
    return out;
  }
 

Ensuite, vous pouvez l'utiliser facilement comme

  for(int codepoint : stringToCodePoints(myString)) {
   ....
 }
 

6voto

alexander.egger Points 1330

Une itération sur les points de code est déposée sous forme de demande de fonctionnalité chez Sun.

Voir l' entrée du bogue du soleil

Il existe également un exemple sur la façon de parcourir une chaîne de points de code.

1voto

Stephen C Points 255558
  • Je ne suis pas sûr de savoir si codepoints qui sont naturellement dans la haute-mères porteuses gamme seront stockées sous forme de deux char les valeurs ou l'un

Ils sont représentés dans une Chaîne de deux caractères.

  • cela semble être une terrible manière coûteuse pour itérer à travers des personnages
  • quelqu'un a dû trouver quelque chose de mieux.

Il n'y a pas de meilleure façon (que @e.e de la solution) qui s'intègre bien avec le langage Java et les bibliothèques comme ils le sont actuellement spécifié.

En théorie, vous pourriez construire un String32 == "string comme une séquence d'Unicode codepoints" de la classe. Dans la pratique, il serait plus de douleur que ce qu'il vaut. Tous de la norme Api Java (et de la 3e partie des bibliothèques) nécessitent une Chaîne et d'en assumer 16 bits caractères. Pour l'utilisation de votre nouvelle classe, vous auriez besoin de remplacer de nombreuses Api avec les versions qui utilisent String32, ou de faire beaucoup de String <-> String32 conversions dans votre code.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X