2017-09-11 1 views
3

Supposons que nous avons une chaîne avec certains (astral) caractères Unicode:Comment obtenir le caractère nième (Unicode) à partir d'une chaîne en JavaScript

const s = 'Hi Unicode!' 

L'opérateur [] et .charAt() méthode ne fonctionnent pas pour obtenir la 4ème caractère, qui devrait être « »:

> s[3] 
'�' 
> s.charAt(3) 
'�' 

le .codePointAt()ne obtenir la valeur correcte pour le 4ème caractère, mais malheureusement, il est un certain nombre et doit être converti ba ck à une chaîne en utilisant String.fromCodePoint():

> String.fromCodePoint(s.codePointAt(3)) 
'' 

De même, la conversion de la chaîne en un tableau en utilisant des icônes donne des caractères Unicode valides, de sorte que c'est une autre façon d'obtenir le 4e:

> [...s][3] 
'' 

Mais je peux » Je crois que passer d'une chaîne à un numéro en chaîne, ou devoir scinder la chaîne en un tableau sont les seuls moyens de faire cette chose apparemment banale. N'y at-il pas une méthode simple pour faire cela?

> s.simpleMethod(3) 
'' 

Note: Je sais que la définition de « caractère » est un peu floue, mais le but de cette question un caractère est tout simplement le symbole qui correspond à un point de code Unicode (pas de caractères combinant, sans groupes de graphèmes, etc).

Mise à jour: la méthode String.fromCodePoint(str.codePointAt(n)) est pas vraiment viable, puisque la n e position, il ne prend pas les symboles astraux précédents en compte: String.fromCodePoint(''.codePointAt(1)) // => '�'


(je me sens un peu stupide de demander cela, comme je suis probablement manquer quelque chose d'évident. Mais previous answers à cette question ne fonctionnent pas sur les chaînes avec Unicode SYMBOLES sur des plans astral.)

+1

Avez-vous vu cette page https: //developer.mozilla.org/fr-fr/docs/Web/JavaScript/Références/Global_Objects/String/charAt avec des exemples de code? – ivo

+0

@ivo non, je n'avais pas vu ça, intéressant! Les exemples de code ont une version "fixe" de charAt, ce qui est utile, mais je me demandais s'il y avait une bonne méthode déjà sauvegardée dans la langue – epidemian

+0

C'est Javascript. Les choses simples ne peuvent pas être si simples :) – jorgonor

Répondre

3

la iterator chaîne est la seule chose qui itère par points de code plutôt que UCS-2/le code UTF-16 unités. Alors:

Donc, pour obtenir un point de code spécifique en fonction de son indice d'une chaîne:

const string = 'Hi Unicode!'; 
// Note: The spread operator uses the string iterator under the hood. 
const symbols = [...string]; 
symbols[3]; // '' 

Pourtant, cela romprait avec des grappes de graphèmes, ou des séquences emoji telles que ‍‍‍ ( + U+200D ZERO WIDTH JOINER + + U+200D ZERO WIDTH JOINER + + U+200D ZERO WIDTH JOINER + ). Text segmentation aide avec cela. Cependant, est-ce que vous avez réellement besoin du 4ème point de code dans la chaîne? Quel est votre cas d'utilisation?

+0

Eh bien, pour gérer ce que vous caractérisez comme "rupture", et dont le OP spécifiquement mentionné, il ne se soucie pas de, nécessiterait une logique spécialisée pour les langages individuels, tels que Kannada, qui a également des groupes complexes qui ne peuvent être composées que par des algorithmes assez complexes. –

+0

Merci Mathias! Votre article sur Unicode est super complet! Ok, donc la méthode de spat de tableau est probablement la plus simple alors. C'est ... pas trop génial je suppose. En réponse à votre question concernant le fait d'avoir réellement besoin du 4ème point de code: non, mon cas d'utilisation original impliquait seulement le premier. J'ai remarqué que 'str [0]' ne fonctionnait pas pour certains personnages, alors j'ai fini par me demander "attends, comment diable obtenez-vous un personnage spécifique d'une chaîne dans JS?", Et nous voilà ... – epidemian

0

Vous pouvez utiliser le nouveau drapeau u pour effectuer un regexp s'il est disponible.

const chars = 'Hi Unicode!'.match(/./ug); 
 
console.log(chars);