Supprimer les accents/caractères diacritiques dans une chaîne de caractères en JavaScript
Comment puis-je supprimer des caractères accentués à partir d'une chaîne?
Surtout dans IE6, j'ai eu quelque chose comme ceci:
accentsTidy = function(s){
var r=s.toLowerCase();
r = r.replace(new RegExp(/\s/g),"");
r = r.replace(new RegExp(/[àáâãäå]/g),"a");
r = r.replace(new RegExp(/æ/g),"ae");
r = r.replace(new RegExp(/ç/g),"c");
r = r.replace(new RegExp(/[èéêë]/g),"e");
r = r.replace(new RegExp(/[ìíîï]/g),"i");
r = r.replace(new RegExp(/ñ/g),"n");
r = r.replace(new RegExp(/[òóôõö]/g),"o");
r = r.replace(new RegExp(/œ/g),"oe");
r = r.replace(new RegExp(/[ùúûü]/g),"u");
r = r.replace(new RegExp(/[ýÿ]/g),"y");
r = r.replace(new RegExp(/\W/g),"");
return r;
};
mais IE6 qui me dérange, il semble qu'il n'aime pas mon expression régulière.
- pourquoi sur terre serait vous voulez supprimer les accents? Cela ressemble à une sorte de forcé l'Anglicisation de noms.... et un pauvre à qui. '山田太郎" serait juste de devenir une chaîne vide.
- Je veux trier par ordre alphabétique dans un véritable ordre alphabétique, sans avoir les lettres accentuées systématiquement à la fin. Je Peux ? (Et je suis français, donc anglicisation... 🙂 )
- Les réponses ici semblent ignorer la question de la normalisation. Une solution robuste qui vous auriez à chercher à faire le genre de choses qui sont effectuées par des github.com/walling/unorm .
- Certains logiciels ne permettent pas de caractères spéciaux dans un id d'emplacement. (PAGE HTML NOMS par exemple) C'est une autre raison de vouloir les supprimer. Garder le titre dans sa forme originale, mais ne pas avoir à retaper tous ces personnages.
- votre exemple serait formidable pour la validation, mais pas de désinfection. Si la chaîne de caractères qu'un utilisateur saisit a des limites, ils ont besoin de savoir cela et être invité à entrer la chaîne de caractères avec les contraintes prévues. L'OP est en fait juste pour le tri et pas pour des changements permanents pour les données. OP serait probablement bénéficier de tri à l'aide de la localeCompare() méthode qui va vous permettre de trier les chaînes en fonction des paramètres régionaux du navigateur (pour la même raison à l'utilisation toLocaleString() lorsque l'on travaille avec les dates)
- avez-vous essayé d'utiliser localeCompare ? "ca".localeCompare("ça") me donne -132 dans google Chrome. Le navigateur de paramètres régionaux ne vous dira jamais que "c" est égal à "ç". Et c'est très bien, car il ne devrait pas. Ils sont en effet différents.
- J'ai fouillé un peu plus sur la question. La spécification de ne pas appliquer quelque chose au sujet de la locale (je ne peux pas savoir ce que le navigateur va le faire), mais recommande que les navigateurs transcrire la chaîne de caractères en Unicode Forme Normalisée (unicode.org/reports/tr15/#Norm_Forms). Dans cette forme de "ç" est traduit dans le caractère 'c' plus le caractère 'cédille'. Ce n'est pas ce que je veux.
- Je ne suis pas sûr que cela travail dans ma situation, étant donné que l'utilisateur est entré dans le titre requis est le titre de l'article. Il serait déraisonnable pour moi de leur demander de modifier leur titre (sauf peut-être si ils ont écrit des articles au sujet de l'encodage) Mais leur "C est la vie." - c'est leur titre, j'ai besoin que les données, juste mes modifications de la structure à à "cest_la_vie".. ne sais Pas si je suis clair mais c'est mon affaire, probablement rien à voir avec l'OP
- Possible dup stackoverflow.com/questions/863800/...
- Ceci est très utile pour les recherches de trop. Je suis en train de construire une recherche d'entrée de boîte où vous tapez joueur de football les noms de tous les coins du monde et je veux d'auto-complétion. Devinez ce que dans ma langue, il n'y a pas de signes diacritiques il est donc difficile pour moi de taper des noms comme "López" ou "Óscar'
- IE6 problème peut être dû au fait que RE d'origine constructeur arguments sont censés être des chaînes de caractères ("PATTERN" [, flags])
new RegExp("ab+c", "g");
et déjà créé objet regexp source - Cela est inexact, puisque vous êtes seulement sur certains des caractères accentués. Par exemple, si seulement compter avec des signes diacritiques, nous avons une longue liste de "áàăắằẵẳaáàâǎâấầẫẩaǎaaaåǻåäääääǟãããaȧȧǡąąąąąąąąąąāąąąąąąāāāāāā aáàâäāåảȁȃạạạặậạạạḁⱥaᶏɑɑɑaᶐ" et il n'est pas encore la liste complète. En outre, le dictionnaire n'est pas la même dans toutes les langues. Par exemple tchèque envisager CH un caractère distinct et de le mettre juste après H. Certaines langues comme le norvégien mettre les caractères accentués "æøå" à la fin de l'alphabet au lieu
- Dans les vieux jours CH est également une lettre en espagnol alphabet placé après le C, CH sera après CZ. Donc enlever tous les signes diacritiques et de tri n'est pas une bonne façon d'aller.
- Voici un cas d'utilisation: Dans geocaching.com/geocache/... il est le code utilisé dans l'énigme avec une opération demandant de remplacer les lettres par des nombres A=1, B=2, C=3, ... puis ajouter chacun de ces numéros. Dans ce code, É sera de 5 aussi, comme l'E.
- La meilleure façon serait pour tout le monde pour réaliser que
a
eta with something
est encore una
... et supprimer l'ensemble "diacritique lettres de lettres!" chose du monde... malheureusement, je doute que cela va être fait, mais l'espoir meurt en dernier... - Double Possible de Efficacement remplacer tous les caractères accentués dans une chaîne de caractères?
- Pensez à mettre à jour votre réponse pour ma réponse qui est plus up-to-date/actuel, à l'aide de ES6.
- L'on a accepté la réponse est obsolète et il y a une BIEN meilleure solution énumérés ci-dessous. Les gens peuvent venir sur cette page et en fait utiliser cette solution. Veuillez mettre à jour votre réponse.
- Ceci est un XY problème! Si vous êtes en essayant de trier des chaînes de caractères comme
e
<é
<f
, puis vous effectuez Unicode classement — de sorte que vous devriez utiliser l' (personnalisable, dépendant de paramètres régionaux) Unicode collation algorithm, mis en œuvre par leIntl.Collator
en JavaScript. - Sûr, mais quand la question a été posée, je ne sais pas ce que je doit attendre 3 ans pour l'Intl.Collateur de spec à être défini.
- Compte tenu de l'état JS était en 2009, vous n'êtes pas du tout dans le mauvais. Mais je pense que de très nombreux Googlers va se retrouver avec le même objectif que le vôtre (quelle autre raison est là pour éliminer les signes diacritiques?) et il vaut la peine de mentionner que
Intl.Collator
existe maintenant de résoudre le X problème, tout comme @LewisDiamond mentionné quenormalize('NFD')
existe maintenant de résoudre le Y problème. - convenu Intl.Collateur est probablement ce que l'OP a été à la recherche pour. J'ai ajouté l'info à ma réponse à assurez-vous que les gens ont deux options en fonction de ce dont ils ont besoin.
- pourquoi faites-vous
new RegExp(/foo/g)
au lieu de simplement/foo/g
(ce qui crée une instance deRegExp
?
Vous devez vous connecter pour publier un commentaire.
Avec ES2015/ES6 Chaîne de caractères.Le Prototype.Normalize(),
Deux il se passe des choses ici:
normalize()
ingNFD
Unicode forme normale se décompose combiné graphèmes dans la combinaison de plus simple. Leè
deCrème
finit exprimé ene
+̀
.g
lobally se débarrasser des signes diacritiques, qui le standard Unicode idéalement groupes comme le La Combinaison Des Signes Diacritiques blocs Unicode.Voir le commentaire de l'essai de performance.
Alternativement, si vous voulez juste de tri
Intl.Collateur a suffisamment de soutien ~85% dès maintenant, un polyfill est également disponible ici mais je n'ai pas testé.
'ąśćńżółźćę'.normalize('NFD').replace(/[\u0300-\u036f]/g, "")
->ascnzołzce
(manque le match pourł
->l
).ł
est une lettre en lui-même, pas un caractère accentuéL
. Par conséquent, il ne devrait pas être modifié pourl
.\u0142
---SI--->'ł'.replace(/\u0142/g, "l")
L
.æø
J'ai légèrement modifié khel version pour une raison: Tous les regexp analyser/remplacer coût O(n) opérations, où n est le nombre de caractères dans le texte cible. Mais, regexp n'est pas exactement ce dont nous avons besoin. Donc:
JS:
Pour tester ma théorie, j'ai écrit un test en http://jsperf.com/diacritics/12. Résultats:
Tests en Chrome 28.0.1500.95 32 bits sur Windows 8 64-bit:
À L'Aide De Regexp
4,558 ops/sec ±4.16%. 37% plus lent
Le Générateur de chaîne de style
7,308 ops/sec ±4.88%. plus rapide
Mise à jour
Tests en Chrome 33.0.1750 sur Windows 8 64-bit:
Utilisation Des Regexp
5,260 ±1.25% ops/sec 76% plus lent
À l'aide de @skerit version
22,138 ±2.12% ops/sec plus rapide
Mise à jour - 19/03/2014
Ajoutant manquant "OE" les signes diacritiques.
Mise à jour - 27/03/2014
À l'aide d'un moyen plus rapide à travers une chaîne à l'aide de js - "Quoi?" Version
Mise à jour - 14/05/2014
Wiki de la communauté
letters.charAt(i)
etletters.length
fonctionne très bien dans google Chrome (je n'ai pas testé d'autres navigateurs). Oh, et un petit conseil: c'est le seul endroit où vous utilisez des guillemets, il brise la cohérence d'avertissement dans mon JSHint. 🙂charAt
. Pourtant, le test lien ne parvient pas à prendre le coût de lasplit
fonctionnement en compte. J'ai essayé de le faire apparaître dans une nouvelle version du test (jsperf.com/charat-or-array/2), etcharAt
dans ce cas est nettement plus rapide. Si mon test (et mon raisonnement) est correcte, cela vous donnera une chance poursplit
+ accès au tableau de chaînes de caractères, qui dans la carte ne sont pas. Qu'en pensez-vous?'\u00DF'.toUpperCase()
évalue à "SS", je pense que la conversion de\u00DF
de ss est le droit de bouger. Le post étant un wiki de la communauté, peut-être @CodingYourLife de contribuer au changement que vous avez fait?.replace(/[\u0301\u0060]/gi,'')
à la fin pour supprimer l'espace vide avec des accents. Parfois dans Mac OS, è peut être e`ʏ
->Ue
,ð
->d
, Changement:ä
->ae
,ö
->oe
,ü
->ue
,Ä
->Ae
,Ö
->Oe
,Ü
->Ue
,å
->aa
,Å
->Aa
,ß
->ss
,ẞ
->SS
,ij
->ij
etIJ
->IJ
.Une version plus complète avec la casse de soutien, des ligatures et autres joyeusetés.
Original source: http://lehelk.com/2011/05/06/script-to-remove-diacritics/
changes
à elle.{ base: "oe", letters: /[\u0153]/g }
) et Œ ({ base: "OE", letters: /[\u0152]/g }
) sont manquantes. Il existe peut-être plus, mais depuis l'OP mentionné ci, je pense qu'ils devraient être ajoutés.ʏ
->Ue
,ð
->d
, Changement:ä
->ae
,ö
->oe
,ü
->ue
,Ä
->Ae
,Ö
->Oe
,Ü
->Ue
,å
->aa
,Å
->Aa
,ß
->ss
,ẞ
->SS
,ij
->ij
etIJ
->IJ
.Le format de new RegExp est
Si vous voulez
ő
,ű
Raccourcie de code basé sur l'excellente solution par Ian Elliott:
Edit: correction de la non-code de travail
Vous pouvez utiliser le
_.ébavurer
méthode de la Lodash bibliothèque.Il est disponible comme un stand-alone MNP paquet
lodash.ébavurer
, ou dans le cadre de lalodash
paquet.Le résultat sera :
"Mon cafe est plein de cafeine"
Une solution qui me semble être la manière la plus rapide par la donnée de test : http://jsperf.com/diacritics/9
De travail exemple: http://jsbin.com/sovorute/1/edit
Raisonnement: l'Une des raisons c'est beaucoup plus rapide est parce que nous ne itérer sur les caractères spéciaux, choisis par le nié regex modèle. Le plus rapide des essais (Chaîne d'Itération sans) itère 1001 sur le texte donné, ce qui signifie chaque personnage. Ce on itère seulement 35 fois et les sorties de l' même résultat. Gardez à l'esprit que cela ne fera que remplacer ce qui est indiqué dans la carte.
Classique article sur le sujet: http://alistapart.com/article/accent-folding-for-auto-complete
De crédit: http://semplicewebsites.com/removing-accents-javascript , fournit également une belle carte des caractères.
Un moyen plus simple de remplacer la diacriticals.
Dans MNP il y a un paquet pour cette: latinize
C'est un très bon package pour résoudre ce problème.
J'ai fourche billyle code de
http://jsfiddle.net/billybraga/UHmnf/ (à partir de son post) dans cette: http://jsfiddle.net/infralabs/dJX58/
J'ai corrigé la transcription de ſ et ß caractères, et a également ajouté coversion de ceux-ci: Þþ, Ðð, Ŋŋ, IJij, Œ.
La modification de l'extrait de code ci-dessous:
Il y en a beaucoup là-bas, mais je pense que celui-ci est simple et assez bon:
Si vous souhaitez également supprimer les caractères spéciaux et de transformation des espaces et des tirets de soulignement, faites ceci:
Voici ma version modifiée de lehelk.com's version qui supprime également les entités html sont des accents :
http://jsfiddle.net/billybraga/UHmnf/
Je ne sais toujours pas sur les performances, mais...
Voici une solution très simple, sans trop de code à l'aide d'une très simple carte de signes diacritiques qui comprend que la carte d'équivalents ascii contenant plus d'un caractère, c'est à dire Æ => AE, ffi => ffi, etc... Également inclus des tests fonctionnels
Ä
->Ae
est correct, maisÄ
->A
est plus probable que les locuteurs de l'anglais allez taper. Je vais traiter mes cordes avec cela, suivie par la .normalize() fonction par Lewis réponse. Grand que vous attraper,Ø
- >O
, mais j'aurai besoin d'ajouterł
->l
😉merci à tous
J'utilise cette version et dire pourquoi (parce que je manque des explications au début, j'ai donc essayer d'aider le prochain lecteur s'il est aussi terne que moi ...)
Remarque : je voulais une solution efficace, donc :
etc ...
Ma version est :
(il n'y a pas de nouvelle astuce technique à l'intérieur, seuls quelques élus + explications)
et je l'utilise de cette façon :
Commentaires :
Je fournis cette réponse pour une question similaire. Il est basé sur rapide tableau de la recherche de remplacement pour certains caractères latins (1+2), l'un pour l'autre (impossible de changer l'allemand ü pour "ue"), mais fonctionne bien pour la base de "normalisation" ASCII de 7 bits.
Les autres caractères sont convertis ?, qui est le résultat est certainement l'ASCII 7 bits. Pas de regex, pas de magie, simple char tableau de travail.
str.normalize('NFD').replace(/[\u0300-\u036f]/g, "")
version. Maintenant - ce qui est bon pour le plus général, celui-liner. Chose étrange, c'est que dans Java boucle version est beaucoup plus rapide, mais il est basé surStringBuilder
. Je ne suis pas sûr de savoir si split/join est à blâmer, mais au moins je sais que je peux oublier cette version de JS/web. 🙂J'ai utilisé string.js's latinise() méthode, qui permet de faire comme ceci:
En supposant que vous savez ce que vous faites, je soupçonne IE6 n'est pas l'interprétation de l'encodage du fichier correctement, et donc en ne reconnaissant pas les caractères non-ASCII dans le fichier:
(Il "sent" mal, j'aurais l'air en faisant le tri, par exemple sur le serveur à l'aide de quelque chose qui est locale-courant... mais quand même...)
Passer d'une fonction définie par l'utilisateur à l'
Array.sort()
méthode, et dans cette fonction définie par l'utilisateur utilisationString.localeCompare()
["ép", "ep", "fp"]
est triée comme["ep", "fp", "ép"]
. Savez-vous pourquoi la lettref
est entre les lettrese
etè
?Ce fait pour moi. JavaScript, Scripts Google Apps, GAZ
čŘůľě
)ăĂâÂțȚţŢșȘşŞ
Vous gotta catch 'em all 🙂Je sais que c'est de la "triche" pour ce faire, sur le côté serveur, mais la semaine dernière j'ai eu une tâche similaire en Javascript et j'ai introduit un simple servlet java et supprimé les accents en Java. C'était très rapide 🙂
J'ai trouvé toutes ces un peu maladroite et je ne suis pas trop expert sur les expressions régulières, voici donc une version plus simple. Il serait assez facile de le traduire à vos favoris langage côté serveur, en supposant que la chaîne de caractères déjà en Unicode:
Vous pouvez créer des regex dans de multiples façons. À l'aide de la nouvelle
RegExp
-constructeur:Ou en utilisant les regex notation littérale:
Vous avez mélangé les deux.
Si vous êtes ouvert à l'aide d'une bibliothèque, vous pouvez utiliser String.js latinize:
http://stringjs.com/#methods/latinise
La retirez-les accents MNP est un forfait de manière assez facile de traiter ces questions:
Tous les ci-dessus ne fonctionne pas avec décomposé caractère utilisé sur Mac OS.
Afin de supprimer les signes diacritiques dans ce cas, il est plus simple :
voir le commentaire de Olivier Miakinen sur :
https://groups.google.com/d/msg/fr.comp.lang.regexp/6IGJTbedGTM/G0sB2kAsR34J
(publié en français)