Comment mettre en majuscule la première lettre d'une chaîne en JavaScript?

3766

Comment puis-je mettre la première lettre d'une chaîne en majuscules sans changer la casse des autres lettres?

Par exemple:

  • "this is a test" -> "This is a test"
  • "the Eiffel Tower" -> "The Eiffel Tower"
  • "/index.html" -> "/index.html"
Robert Wills
la source
12
Underscore a un plugin appelé underscore.string qui inclut cela et un tas d'autres excellents outils.
Aaron
qu'en est-il de:return str.replace(/(\b\w)/gi,function(m){return m.toUpperCase();});
Muhammad Umer
111
Plus simple:string[0].toUpperCase() + string.substring(1)
dr.dimitru
7
`${s[0].toUpperCase()}${s.slice(1)}`
noego
([initial, ...rest]) => [initial.toUpperCase(), ...rest].join("")
Константин Ван

Réponses:

5813

La solution de base est:

function capitalizeFirstLetter(string) {
  return string.charAt(0).toUpperCase() + string.slice(1);
}

console.log(capitalizeFirstLetter('foo')); // Foo

Certaines autres réponses sont modifiées String.prototype(cette réponse aussi), mais je déconseille cela maintenant en raison de la maintenabilité (difficile de savoir où la fonction est ajoutée à la prototypeet pourrait provoquer des conflits si un autre code utilise le même nom / un navigateur ajoute une fonction native avec ce même nom à l'avenir).

... et puis, il y a tellement plus à cette question quand on considère l'internationalisation, comme montre cette étonnamment bonne réponse (enterrée ci-dessous).

Si vous souhaitez travailler avec des points de code Unicode au lieu d'unités de code (par exemple pour gérer des caractères Unicode en dehors du plan multilingue de base), vous pouvez tirer parti du fait que cela String#[@iterator]fonctionne avec des points de code, et vous pouvez utiliser toLocaleUpperCasepour obtenir des majuscules correctes pour les paramètres régionaux:

function capitalizeFirstLetter([ first, ...rest ], locale = navigator.language) {
  return [ first.toLocaleUpperCase(locale), ...rest ].join('');
}

console.log(capitalizeFirstLetter('foo')); // Foo
console.log(capitalizeFirstLetter("𐐶𐐲𐑌𐐼𐐲𐑉")); // "𐐎𐐲𐑌𐐼𐐲𐑉" (correct!)
console.log(capitalizeFirstLetter("italya", 'tr')); // İtalya" (correct in Turkish Latin!)

Pour encore plus d'options d'internationalisation, veuillez consulter la réponse d'origine ci-dessous .

Steve Harrison
la source
9
substring est comprise dans plus de navigateurs que substr
mplungjan
6
à ajouter à karim79 - il est probablement exagéré d'en faire une fonction car javascript fera la même chose pour la variable sans le wrapping de fonction. Je suppose qu'il serait plus clair d'utiliser une fonction, mais son natif sinon, pourquoi la compliquer avec un wrapper de fonction?
Ross
18
Ne devrions-nous pas aussi toLowerCase la tranche (1)?
hasen
177
Non, parce que l'OP a donné cet exemple: the Eiffel Tower -> The Eiffel Tower. De plus, la fonction n'est capitaliseFirstLetterpas appelée capitaliseFirstLetterAndLowerCaseAllTheOthers.
ban-geoengineering
22
Personne ne se soucie de la règle importante de la POO? - Ne modifiez jamais des objets que vous ne possédez pas? . BTW, ce one-liner a l'air beaucoup plus élégant:string[0].toUpperCase() + string.substring(1)
dr.dimitru
1350

Voici une approche plus orientée objet:

String.prototype.capitalize = function() {
    return this.charAt(0).toUpperCase() + this.slice(1);
}

Vous appelleriez la fonction, comme ceci:

"hello world".capitalize();

Avec la sortie attendue étant:

"Hello world" 
Steve Hansell
la source
24
J'aime cette solution parce que c'est comme Ruby, et Ruby est doux! :) Je minuscule toutes les autres lettres de la chaîne pour qu'elle fonctionne exactement comme Ruby:return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
ma11hew28
164
Dans ce monde post-Prototype.js, il n'est pas suggéré de modifier ou d'étendre les objets natifs.
Ryan
191
@rxgx - Le boogeyman "ne pas étendre" commence maintenant à s'éteindre (Dieu merci), et les gens tirent la tête hors du jSand et se rendent compte que ce n'est qu'une fonctionnalité de langage. Ce n'est pas parce que Prototype.js a étendu l'objet lui-même pendant une courte période que l'extension des indigènes est mauvaise. Vous ne devriez pas le faire si vous écrivez du code pour un consommateur inconnu (comme un script d'analyse qui va sur des sites aléatoires), mais à part ça, ça va.
csuwldcat
44
@csuwldcat Et si une autre bibliothèque que vous utilisez ajoute sa propre majuscule sans que vous le sachiez? L'extension des prototypes est une mauvaise forme, que Prototype.js l'ait fait ou non. Avec ES6, les intrinsèques vous permettront d'avoir votre gâteau et de le manger aussi. Je pense que vous pourriez confondre le "boogeyman" qui meurt pour les personnes créant des cales conformes à la spécification ECMASCRIPT. Ces shims sont parfaitement bien car une autre bibliothèque qui a ajouté un shim l'implémenterait de la même manière. Cependant, l'ajout de vos propres éléments intrinsèques non spécifiés doit être évité.
Justin Meyer
44
L'extension des indigènes est EXTRÊMEMENT mauvaise pratique. Même si vous dites "oh je ne vais jamais utiliser ce code avec autre chose", vous (ou quelqu'un d'autre) le ferez probablement. Ensuite, ils passeront trois jours à essayer de comprendre un bug mathématique étrange parce que quelqu'un a étendu Number.money () pour traiter une devise légèrement différente de celle de votre autre bibliothèque. Sérieusement, j'ai vu cela se produire dans une grande entreprise et cela ne vaut la peine de déboguer personne pour découvrir une bibliothèque dévouée avec les prototypes indigènes.
phreakhead
574

En CSS:

p:first-letter {
    text-transform:capitalize;
}
sam6ber
la source
80
OP demande une solution JS.
Antonio Max
129
$ ('# mystring_id'). text (string) .css ('text-transform', 'capitalize');
DonMB
21
De plus, cela affecte uniquement l'affichage de la chaîne - pas la valeur réelle. Si c'est sous une forme, par exemple, la valeur sera toujours soumise telle quelle.
dmansfield
12
Cette réponse m'a aidé à réaliser qu'une solution CSS était vraiment plus appropriée à ce que je faisais. @dudewad: La réponse devrait probablement indiquer que ce n'est pas une solution JS mais qu'elle pourrait être plus appropriée en fonction des besoins.
joshden
58
Pour environ 80% des téléspectateurs venant à cette question, ce sera la meilleure réponse. Pas une réponse à la question , mais plutôt au problème .
Jivan
290

Voici une version abrégée de la réponse populaire qui obtient la première lettre en traitant la chaîne comme un tableau:

function capitalize(s)
{
    return s[0].toUpperCase() + s.slice(1);
}

Mise à jour:

Selon les commentaires ci-dessous, cela ne fonctionne pas dans IE 7 ou ci-dessous.

Mise à jour 2:

Pour éviter undefinedles chaînes vides (voir le commentaire de @ njzk2 ci-dessous ), vous pouvez rechercher une chaîne vide:

function capitalize(s)
{
    return s && s[0].toUpperCase() + s.slice(1);
}
joelvh
la source
23
Cela ne fonctionnera pas dans IE <8, car ces navigateurs ne prennent pas en charge l'indexation des chaînes. IE8 lui-même le prend en charge, mais uniquement pour les littéraux de chaîne - pas pour les objets de chaîne.
Mathias Bynens
52
peu importe, le marché IE7 est inférieur à 5%! et ce sont probablement la vieille machine de votre gremma et grempa. Je dis le code court FTW!
vsync
@MathiasBynens Savez-vous si cela affecte des navigateurs non IE plus anciens ou juste IE7? Si aucun autre navigateur n'est affecté par l'indexation des littéraux de chaîne en 2014, cela devrait aller. :)
hexalys
3
@vsync Je voulais juste dire qu'en fonction de la démographie de vos utilisateurs, parfois (bien que de moins en moins avec reconnaissance à mesure que nous passons en 2014 et au-delà), il est rentable de prendre en charge les anciens navigateurs comme IE7 ...
joshuahedlund
2
@ njzk2 pour gérer une chaîne vide, vous pouvez mettre à jour ceci: return s && s[0].toUpperCase() + s.slice(1);
joelvh
188

Si vous êtes intéressé par les performances de quelques méthodes différentes publiées:

Voici les méthodes les plus rapides basées sur ce test jsperf (classées du plus rapide au plus lent).

Comme vous pouvez le voir, les deux premières méthodes sont essentiellement comparables en termes de performances, alors que la modification de la String.prototypeest de loin la plus lente en termes de performances.

// 10,889,187 operations/sec
function capitalizeFirstLetter(string) {
    return string[0].toUpperCase() + string.slice(1);
}

// 10,875,535 operations/sec
function capitalizeFirstLetter(string) {
    return string.charAt(0).toUpperCase() + string.slice(1);
}

// 4,632,536 operations/sec
function capitalizeFirstLetter(string) {
    return string.replace(/^./, string[0].toUpperCase());
}

// 1,977,828 operations/sec
String.prototype.capitalizeFirstLetter = function() {
    return this.charAt(0).toUpperCase() + this.slice(1);
}

entrez la description de l'image ici

Josh Crozier
la source
1
Il semble que le code d'initialisation ne fasse pas la différence non plus: jsperf.com/capitalize-first-letter-of-string/2
user420667
6
Notez également que le remplacement .slice(1)par .substr(1)améliorerait encore les performances.
Przemek
2
Considération raisonnable. Gardez à l'esprit que dans de nombreux cas, les performances ne sont même pas perceptibles: même l'approche "la plus lente" gérerait des chaînes de 19k en 10 ms. Prenez donc celui qui vous convient le mieux.
Citant Eddie
1
Au cas où quelqu'un serait curieux (comme moi) de savoir comment ses performances ont augmenté au cours des quatre dernières années, les ops / sec de la troisième fonction sur un macbook pro 2018 sont à 135307 869, donc essentiellement 12,4 fois plus rapides.
Carlo Field
151

Pour un autre cas, j'en ai besoin pour mettre en majuscule la première lettre et minuscule le reste. Les cas suivants m'ont fait changer cette fonction:

//es5
function capitalize(string) {
    return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();
}
capitalize("alfredo")  // => "Alfredo"
capitalize("Alejandro")// => "Alejandro
capitalize("ALBERTO")  // => "Alberto"
capitalize("ArMaNdO")  // => "Armando"

// es6 using destructuring 
const capitalize = ([first,...rest]) => first.toUpperCase() + rest.join('').toLowerCase();
alejandro
la source
1
"... mais ne changez pas la casse des autres lettres". Ce n'est pas une bonne réponse à la question posée par le PO.
Carlos Muñoz
2
@ CarlosMuñoz si vous lisez la phrase d'ouverture, il dit que c'est pour un cas différent.
TMH
3
@TomHart C'est exactement pourquoi ce n'est pas une solution à la question. Ce devrait être un commentaire ou une autre question et réponse
Carlos Muñoz
15
Je suis d'accord avec vous là-dessus, mais je peux voir beaucoup de gens se retrouver ici pour faire ce que fait cette réponse.
TMH
74

Voici la solution ECMAScript 6+ 2018 :

const str = 'the Eiffel Tower';
const newStr = `${str[0].toUpperCase()}${str.slice(1)}`;
console.log('Original String:', str); // the Eiffel Tower
console.log('New String:', newStr); // The Eiffel Tower

Sterling Bourne
la source
5
.slice()est plus lent que .substring(), str[0]serait undefinedpour une chaîne vide et l'utilisation de littéraux de modèle pour joindre les deux parties introduit ici 8 caractères, alors qu'il +n'en introduirait que 3.
Przemek
4
Le point de ma réponse Prz est de présenter les nouvelles fonctionnalités prises en charge par ES6, en particulier les modèles de littéraux qui n'ont pas été mentionnés dans d'autres articles. L'idée de StackOverflow est de donner au chercheur des «options». Ils peuvent prendre le concept de littéraux de modèle décrit dans cette réponse et le combiner avec des améliorations à micro-vitesse comme Substring v. Slice si leur application nécessite ces millisecondes supplémentaires enregistrées. Ma réponse n'inclut pas non plus de test unitaire, ce qui montre que vous ne devez jamais copier directement une réponse StackOverflow. Je suppose que le développeur prendra ma réponse et l'adaptera.
Sterling Bourne
Vous ne gagnez rien à utiliser les littéraux de modèle ici et cela ${}ajoute juste du bruit. const newStr = str[0].toUpperCase() + str.slice(1);est plus facile à lire.
Boris
1
Acceptez ensuite d'être en désaccord sur ce qui est plus facile à lire.
Sterling Bourne
67

Si vous utilisez déjà (ou envisagez) d'utiliser lodash, la solution est simple:

_.upperFirst('fred');
// => 'Fred'

_.upperFirst('FRED');
// => 'FRED'

_.capitalize('fred') //=> 'Fred'

Voir leurs documents: https://lodash.com/docs#capitalize

_.camelCase('Foo Bar'); //=> 'fooBar'

https://lodash.com/docs/4.15.0#camelCase

_.lowerFirst('Fred');
// => 'fred'

_.lowerFirst('FRED');
// => 'fRED'

_.snakeCase('Foo Bar');
// => 'foo_bar'

Vanilla js pour le premier majuscule:

function upperCaseFirst(str){
    return str.charAt(0).toUpperCase() + str.substring(1);
}
chovy
la source
11
Je pense que la préférence devrait être pour vanilla Js car la plupart des gens ne téléchargeront pas un framework entier uniquement pour capitaliser une chaîne.
GGG
7
Jusqu'à présent, dans tous mes projets, je n'ai jamais utilisé le lodash. N'oubliez pas non plus que la plupart des utilisateurs de Google finiront sur cette page, et répertorier un cadre comme alternative est bien, mais pas comme réponse principale.
GGG
2
Puisque d'autres réponses utilisent vanilla js, c'est bien d'avoir une réponse comme celle-ci, car beaucoup d'entre nous utilisent lodash / underscore.
Lu Roman
1
Ce n'est pas la bonne réponse car l'OP demande maintenant de le faire en Javascript, pas une bibliothèque Javascript, qui importe une bibliothèque entière en tant que dépendance à votre projet. Ne l'utilisez pas.
dudewad
1
La question du PO est en vanille à la fin de ma réponse.
chovy
62

Mettez en majuscule la première lettre de tous les mots d'une chaîne:

function ucFirstAllWords( str )
{
    var pieces = str.split(" ");
    for ( var i = 0; i < pieces.length; i++ )
    {
        var j = pieces[i].charAt(0).toUpperCase();
        pieces[i] = j + pieces[i].substr(1);
    }
    return pieces.join(" ");
}
Dan
la source
14
Relire la question: je veux mettre en majuscule le premier caractère d'une chaîne, mais ne pas changer la casse des autres lettres.
JimmyPena
2
Je sais que je l'ai fait. J'ajouterais une chose, au cas où la chaîne entière commence en majuscule: pieces [i] = j + pieces [i] .substr (1) .toLowerCase ();
Malovich
4
Une autre solution à ce cas: fonction capitaliseFirstLetters (s) {return s.split ("") .map (function (w) {return w.charAt (0) .toUpperCase () + w.substr (1)}). Join ("")} Peut être une belle ligne si elle n'est pas mise dans une fonction.
Luke Channings
Il serait préférable de commencer par minuscules la chaîne entière
Magico
À part cette fonction qui ne répond pas à la question, elle est en fait également trop compliquée. s => s.split(' ').map(x => x[0].toUpperCase() + x.slice(1)).join(' ')
OverCoder
48

Nous pourrions obtenir le premier personnage avec l'un de mes préférés RegExp, ressemble à un joli smiley:/^./

String.prototype.capitalize = function () {
  return this.replace(/^./, function (match) {
    return match.toUpperCase();
  });
};

Et pour tous les accros au café:

String::capitalize = ->
  @replace /^./, (match) ->
    match.toUpperCase()

... et pour tous les gars qui pensent qu'il existe une meilleure façon de procéder, sans étendre les prototypes natifs:

var capitalize = function (input) {
  return input.replace(/^./, function (match) {
    return match.toUpperCase();
  });
};
yckart
la source
2
Il existe une meilleure façon de procéder sans modifier le prototype String.
Big McLargeHuge
2
@ davidkennedy85 Bien sûr! Mais c'est le moyen le plus simple, pas le meilleur ... ;-)
yckart
Cher lordy, il y a un million de réponses à cette question! Votre solution est encore plus belle dans es6. 'Answer'.replace(/^./, v => v.toLowerCase())
stwilz
47

Utilisation:

var str = "ruby java";

console.log(str.charAt(0).toUpperCase() + str.substring(1));

Il sortira "Ruby java"sur la console.

AMIC MING
la source
Solution en une ligne.
Ahmad Sharif
45

Si vous utilisez underscore.js ou Lo-Dash , la bibliothèque underscore.string fournit des extensions de chaîne, y compris les majuscules:

_.capitalize (string) Convertit la première lettre de la chaîne en majuscules.

Exemple:

_.capitalize("foo bar") == "Foo bar"
andersh
la source
3
Depuis la version 3.0.0 , Lo-Dash dispose de cette méthode de chaîne par défaut. Tout comme décrit dans cette réponse: _.capitalize("foo") === "Foo".
bardzusny
Il existe également une fonction underscore.js utile appelée humanize. Il convertit une chaîne soulignée, camélisée ou dashérisée en une chaîne humanisée. Supprime également les espaces de début et de fin et supprime le suffixe «_id».
Stepan Zakharov
1
A partir de la version 4 *, Lodash met également en minuscule () toutes les autres lettres, attention!
Igor Loskutov
45
String.prototype.capitalize = function(allWords) {
   return (allWords) ? // if all words
      this.split(' ').map(word => word.capitalize()).join(' ') : //break down phrase to words then  recursive calls until capitalizing all words
      this.charAt(0).toUpperCase() + this.slice(1); // if allWords is undefined , capitalize only the first word , mean the first char of the whole string
}

Et alors:

 "capitalize just the first word".capitalize(); ==> "Capitalize just the first word"
 "capitalize all words".capitalize(true); ==> "Capitalize All Words"

Mise à jour de novembre 2016 (ES6), juste pour le FUN:

const capitalize = (string = '') => [...string].map(    //convert to array with each item is a char of string by using spread operator (...)
    (char, index) => index ? char : char.toUpperCase()  // index true means not equal 0 , so (!index) is the first char which is capitalized by `toUpperCase()` method
 ).join('')                                             //return back to string

puis capitalize("hello") // Hello

Abdennour TOUMI
la source
3
Je pense que c'est une mauvaise solution pour 2 raisons: Modifier le prototype d'une primitive est une mauvaise idée. Si la spécification change et qu'ils décident de choisir «capitaliser» comme nouveau nom de propriété de proto, vous rompez la fonctionnalité du langage principal. De plus, le nom de méthode choisi est médiocre. À première vue, je pense que cela capitalisera toute la chaîne. Utiliser un nom plus descriptif tel que ucFirst de PHP ou quelque chose de similaire pourrait être une meilleure idée.
dudewad
L'autre réponse ES6 est plus simple: const capitalize = ([first,...rest]) => first.toUpperCase() + rest.join('').toLowerCase();.
Dan Dascalescu
44

3 solutions LES PLUS COURTES , 1 et 2 traitent les cas lorsque la schaîne est "", nullet undefined:

 s&&s[0].toUpperCase()+s.slice(1)        // 32 char

 s&&s.replace(/./,s[0].toUpperCase())    // 36 char - using regexp

'foo'.replace(/./,x=>x.toUpperCase())    // 31 char - direct on string, ES6

Kamil Kiełczewski
la source
42

CSS uniquement

p::first-letter {
  text-transform: uppercase;
}
  • Bien qu'il soit appelé ::first-letter, il s'applique au premier caractère , c'est-à-dire qu'en cas de chaîne %a, ce sélecteur s'appliquerait à %et en tant que tel ane serait pas mis en majuscule.
  • Dans IE9 + ou IE5.5 +, il est pris en charge en notation héritée avec un seul deux-points ( :first-letter).

ES2015 une doublure

Puisqu'il existe de nombreuses réponses, mais aucune dans ES2015 qui résoudrait efficacement le problème d'origine, j'ai trouvé ce qui suit:

const capitalizeFirstChar = str => str.charAt(0).toUpperCase() + str.substring(1);

Remarques

  • parameters => functionest ce qu'on appelle la fonction flèche .
  • Je suis allé avec nom capitalizeFirstCharau lieu de capitalizeFirstLetter, car OP n'a pas demandé de code qui met en majuscule la première lettre de la chaîne entière, mais le tout premier caractère (si c'est une lettre, bien sûr).
  • constnous donne la possibilité de déclarer capitalizeFirstCharcomme constante, ce qui est souhaité car en tant que programmeur, vous devez toujours indiquer explicitement vos intentions.
  • Dans le benchmark que j'ai effectué, il n'y avait pas de différence significative entre string.charAt(0)et string[0]. Notez cependant que ce string[0]serait undefinedpour une chaîne vide, donc elle devrait être réécrite string && string[0], ce qui est beaucoup trop verbeux, par rapport à l'alternative.
  • string.substring(1)est plus rapide que string.slice(1).

Référence

  • 4 956 962 ops / s ± 3,03% pour cette solution,
  • 4 577 946 ops / s ± 1,2% pour la réponse la plus votée.
  • Créé avec JSBench.me sur Google Chrome 57.

Comparaison des solutions

Przemek
la source
@Green: c'est le cas , êtes-vous sûr d'avoir spécifié le sélecteur avec deux deux points?
Przemek
1
En fait, vous ne voulez pas utiliser le signe plus (+) comme méthode de concaténation dans ES6. Vous voudrez utiliser des modèles de littéraux: eslint.org/docs/rules/prefer-template
Sterling Bourne
42

Il existe un moyen très simple de l'implémenter par replace . Pour ECMAScript 6:

'foo'.replace(/^./, str => str.toUpperCase())

Résultat:

'Foo'
Little Roys
la source
1
Meilleure réponse de loin, et des points supplémentaires pour montrer la syntaxe regex lambda. J'aime particulièrement celui-ci car il peut être un copier-coller fluide n'importe où.
Wade Hatler
L'utilisation /^[a-z]/isera meilleure que l'utilisation, .car la précédente n'essaiera pas de remplacer un caractère autre que les alphabets
Code Maniac
39

Je n'ai vu aucune mention dans les réponses existantes de problèmes liés aux points de code du plan astral ou à l' internationalisation. «Majuscule» ne signifie pas la même chose dans toutes les langues utilisant un script donné.

Au début, je n'ai vu aucune réponse concernant les problèmes liés aux points de code du plan astral. Il y en a un , mais il est un peu enterré (comme celui-ci, je suppose!)


La plupart des fonctions proposées ressemblent à ceci:

function capitalizeFirstLetter(str) {
  return str[0].toUpperCase() + str.slice(1);
}

Cependant, certains caractères placés en dehors du BMP (plan multilingue de base, points de code U + 0 à U + FFFF). Par exemple, prenez ce texte Deseret:

capitalizeFirstLetter("𐐶𐐲𐑌𐐼𐐲𐑉"); // "𐐶𐐲𐑌𐐼𐐲𐑉"

Le premier caractère ici ne parvient pas à mettre en majuscule parce que les propriétés indexées de tableau des chaînes n'accèdent pas aux «caractères» ou aux points de code *. Ils accèdent aux unités de code UTF-16. Cela est également vrai lors du découpage - les valeurs d'index pointent vers les unités de code.

Il se trouve que les unités de code UTF-16 sont 1: 1 avec des points de code USV dans deux plages, U + 0 à U + D7FF et U + E000 à U + FFFF inclus. La plupart des personnages encaissés entrent dans ces deux gammes, mais pas tous.

À partir d'ES2015, le traitement de ce problème est devenu un peu plus facile. String.prototype[@@iterator]renvoie des chaînes correspondant aux points de code **. Ainsi, par exemple, nous pouvons le faire:

function capitalizeFirstLetter([ first, ...rest ]) {
  return [ first.toUpperCase(), ...rest ].join('');
}

capitalizeFirstLetter("𐐶𐐲𐑌𐐼𐐲𐑉") // "𐐎𐐲𐑌𐐼𐐲𐑉"

Pour les cordes plus longues, ce n'est probablement pas terriblement efficace *** - nous n'avons pas vraiment besoin d'itérer le reste. Nous pourrions utiliser String.prototype.codePointAtpour obtenir cette première lettre (possible), mais nous aurions encore besoin de déterminer où la tranche devrait commencer. Une façon d'éviter d'itérer le reste serait de tester si le premier point de code est en dehors du BMP; si ce n'est pas le cas, la tranche commence à 1, et si c'est le cas, la tranche commence à 2.

function capitalizeFirstLetter(str) {
  const firstCP = str.codePointAt(0);
  const index = firstCP > 0xFFFF ? 2 : 1;

  return String.fromCodePoint(firstCP).toUpperCase() + str.slice(index);
}

capitalizeFirstLetter("𐐶𐐲𐑌𐐼𐐲𐑉") // "𐐎𐐲𐑌𐐼𐐲𐑉"

Vous pouvez utiliser des mathématiques au niveau du bit au lieu de > 0xFFFFlà, mais c'est probablement plus facile à comprendre de cette façon et l'une ou l'autre obtiendrait la même chose.

Nous pouvons également faire ce travail dans ES5 et ci-dessous en poussant un peu plus loin cette logique si nécessaire. Il n'y a pas de méthodes intrinsèques dans ES5 pour travailler avec les points de code, nous devons donc tester manuellement si la première unité de code est un substitut ****:

function capitalizeFirstLetter(str) {
  var firstCodeUnit = str[0];

  if (firstCodeUnit < '\uD800' || firstCodeUnit > '\uDFFF') {
    return str[0].toUpperCase() + str.slice(1);
  }

  return str.slice(0, 2).toUpperCase() + str.slice(2);
}

capitalizeFirstLetter("𐐶𐐲𐑌𐐼𐐲𐑉") // "𐐎𐐲𐑌𐐼𐐲𐑉"

Au début, j'ai également mentionné des considérations d'internationalisation. Certains d' entre eux sont très difficiles à expliquer parce qu'ils ont besoin de connaissances non seulement de ce que la langue est utilisée, mais peut aussi exiger des connaissances spécifiques des mots dans la langue. Par exemple, le digraphe irlandais "mb" est mis en majuscule comme "mB" au début d'un mot. Un autre exemple, l'eszett allemand, ne commence jamais un mot (afaik), mais aide toujours à illustrer le problème. L'eszett en minuscule («ß») met en majuscule «SS», mais «SS» peut minuscule en «ß» ou «ss» - vous avez besoin d'une connaissance hors bande de la langue allemande pour savoir ce qui est correct!

L'exemple le plus célèbre de ce genre de problèmes est probablement le turc. En latin turc, la forme majuscule de i est ©, tandis que la forme minuscule de I est ı - ce sont deux lettres différentes. Heureusement, nous avons un moyen de tenir compte de cela:

function capitalizeFirstLetter([ first, ...rest ], locale) {
  return [ first.toLocaleUpperCase(locale), ...rest ].join('');
}

capitalizeFirstLetter("italy", "en") // "Italy"
capitalizeFirstLetter("italya", "tr") // "İtalya"

Dans un navigateur, la balise de langue préférée de l'utilisateur est indiquée par navigator.language, une liste par ordre de préférence est trouvée sur navigator.languages, et la langue d'un élément DOM donné peut être obtenue (généralement) avec Object(element.closest('[lang]')).lang || YOUR_DEFAULT_HEREdans des documents multilingues.

Dans les agents qui prennent en charge les classes de caractères de propriété Unicode dans RegExp, qui ont été introduites dans ES2018, nous pouvons nettoyer davantage les choses en exprimant directement les caractères qui nous intéressent:

function capitalizeFirstLetter(str, locale=navigator.language) {
  return str.replace(/^\p{CWU}/u, char => char.toLocaleUpperCase(locale));
}

Cela pourrait être légèrement modifié pour gérer également plusieurs mots en majuscule dans une chaîne avec une assez bonne précision. La propriété de caractère CWUou Changes_When_Uppercased correspond à tous les points de code qui, ainsi, changent lorsqu'ils sont en majuscule. Nous pouvons essayer cela avec un caractère digraphique en titane comme le néerlandais ij par exemple:

capitalizeFirstLetter('ijsselmeer'); // "IJsselmeer"

Au moment de la rédaction (février 2020), Firefox / Spidermonkey n'avait encore implémenté aucune des fonctionnalités RegExp introduites au cours des deux dernières années *****. Vous pouvez vérifier l'état actuel de cette fonctionnalité dans le tableau compat Kangax . Babel est capable de compiler des littéraux RegExp avec des références de propriété à des modèles équivalents sans eux, mais sachez que le code résultant peut être énorme.


Selon toute vraisemblance, les personnes qui poseront cette question ne seront pas concernées par la capitalisation ou l'internationalisation de Deseret. Mais il est bon d'être conscient de ces problèmes, car il y a de fortes chances que vous les rencontriez éventuellement même si ce ne sont pas des problèmes pour le moment. Ce ne sont pas des cas marginaux, ou plutôt, ce ne sont pas des cas marginaux par définition - il y a tout un pays où la plupart des gens parlent le turc, de toute façon, et la fusion des unités de code avec des points de code est une source assez courante de bogues (en particulier avec en ce qui concerne les emoji). Les chaînes et la langue sont assez compliquées!


* Les unités de code de l'UTF-16 / UCS2 sont également des points de code Unicode dans le sens où, par exemple, U + D800 est techniquement un point de code, mais ce n'est pas ce que cela "signifie" ici ... en quelque sorte ... même si cela devient joli flou. Ce que les substituts ne sont certainement pas, cependant, ce sont les USV (valeurs scalaires Unicode).

** Bien que si une unité de code de substitution est «orpheline» - c'est-à-dire qu'elle ne fait pas partie d'une paire logique - vous pouvez toujours obtenir des substituts ici aussi.

*** peut être. Je ne l'ai pas testé. À moins que vous n'ayez déterminé que la capitalisation est un goulot d'étranglement significatif, je ne le suerais probablement pas - choisissez ce que vous pensez être le plus clair et le plus lisible.

**** une telle fonction pourrait souhaiter tester à la fois la première et la seconde unités de code au lieu de la première, car il est possible que la première unité soit un substitut orphelin. Par exemple, l'entrée "\ uD800x" mettrait en majuscule le X tel quel, ce qui peut ou non être attendu.

***** Voici le problème de Bugzilla si vous souhaitez suivre la progression plus directement.

Point-virgule
la source
2
Cette réponse doit être déplacée vers l'avant.
Rúnar Berg
Merci @ RúnarBerg - puisque votre commentaire m'a rappelé cela, je l'ai relu et j'ai réalisé que j'avais laissé de côté un cas final et une solution qui méritent d'être mentionnés. A également essayé de mieux clarifier une partie de la terminologie.
Point
Grande réponse .....
Ben Aston
Cette réponse est excellente, j'aimerais pouvoir la voter davantage.
David Barker
38

Cela semble plus simple en CSS:

<style type="text/css">
    p.capitalize {text-transform:capitalize;}
</style>
<p class="capitalize">This is some text.</p>

Ceci provient de la propriété CSS text-transform (sur W3Schools ).

Ryan
la source
29
@Simon Il n'est pas indiqué que la chaîne sera nécessairement sortie dans le cadre d'un document HTML - CSS ne sera utile que si c'est le cas.
Adam Hepton
9
Adam, c'est vrai, mais je suppose que plus de 95% du Javascript est utilisé avec HTML et CSS. Malheureusement, l'instruction "capitaliser" capitalise en fait chaque mot , vous aurez donc besoin de JS pour ne mettre en majuscule que la première lettre de la chaîne.
Simon East
18
Incorrect, Dinesh. Il a dit le premier caractère de la chaîne .
Simon East
81
Cette réponse, malgré un nombre ridicule de votes positifs, est tout simplement fausse, car elle mettra en majuscule la première lettre de chaque mot. @Ryan, vous gagnerez un badge Discipliné si vous le supprimez. S'il-vous-plaît faites ainsi.
Dan Dascalescu
10
D'accord avec @DanDascalescu - la réponse de Ryan est complètement fausse.
Timo
38
var capitalized = yourstring[0].toUpperCase() + yourstring.substr(1);
zianwar
la source
37

Il est toujours préférable de gérer ce genre de choses en utilisant d' abord CSS , en général, si vous pouvez résoudre quelque chose en utilisant CSS, allez-y d'abord, puis essayez JavaScript pour résoudre vos problèmes, alors dans ce cas essayez d'utiliser :first-letteren CSS et appliqueztext-transform:capitalize;

Essayez donc de créer une classe pour cela, afin de pouvoir l'utiliser globalement, par exemple: .first-letter-uppercaseet ajoutez quelque chose comme ci-dessous dans votre CSS:

.first-letter-uppercase:first-letter {
    text-transform:capitalize;
}

De plus, l'option alternative est JavaScript, donc le mieux va être quelque chose comme ça:

function capitalizeTxt(txt) {
  return txt.charAt(0).toUpperCase() + txt.slice(1); //or if you want lowercase the rest txt.slice(1).toLowerCase();
}

et appelez-le comme:

capitalizeTxt('this is a test'); // return 'This is a test'
capitalizeTxt('the Eiffel Tower'); // return 'The Eiffel Tower'
capitalizeTxt('/index.html');  // return '/index.html'
capitalizeTxt('alireza');  // return 'Alireza'

Si vous souhaitez le réutiliser encore et encore, il est préférable de le joindre à la chaîne native javascript, donc quelque chose comme ci-dessous:

String.prototype.capitalizeTxt = String.prototype.capitalizeTxt || function() {
    return this.charAt(0).toUpperCase() + this.slice(1);
}

et appelez-le comme ci-dessous:

'this is a test'.capitalizeTxt(); // return 'This is a test'
'the Eiffel Tower'.capitalizeTxt(); // return 'The Eiffel Tower'
'/index.html'.capitalizeTxt();  // return '/index.html'
'alireza'.capitalizeTxt();  // return 'Alireza'
Alireza
la source
36

Si vous souhaitez reformater le texte en majuscules, vous pouvez modifier les autres exemples en tant que tels:

function capitalize (text) {
    return text.charAt(0).toUpperCase() + text.slice(1).toLowerCase();
}

Cela garantira que le texte suivant est modifié:

TEST => Test
This Is A TeST => This is a test
monokrome
la source
Il vaut probablement la peine de noter que cela convertira également des choses comme des acronymes en minuscules, donc peut-être pas la meilleure idée dans la plupart des cas
monokrome
De plus, GAMITG a-t-il vraiment effectué une modification juste pour supprimer un espace blanc d'une partie non codée du message? O_O
monokrome
btw, cela brisera les acronymes majuscules, alors
faites
34
function capitalize(s) {
    // returns the first letter capitalized + the string from index 1 and out aka. the rest of the string
    return s[0].toUpperCase() + s.substr(1);
}


// examples
capitalize('this is a test');
=> 'This is a test'

capitalize('the Eiffel Tower');
=> 'The Eiffel Tower'

capitalize('/index.html');
=> '/index.html'
Fredrik A.
la source
Fait @Ram. Également inclus des exemples.
Fredrik A.
Comment est-ce mieux que la réponse de 2009 ?.
Dan Dascalescu
1
Ce n'est pas @DanDascalescu. Je suppose que vous pourriez faire valoir que substr/ substringest un peu plus sémantique par opposition à slice, mais c'est juste une question de préférence. J'ai toutefois inclus des exemples avec les chaînes fournies dans la question, ce qui est une belle touche non présente dans l'exemple '09. Je pense honnêtement que cela se résume à 15 ans, je veux du karma sur StackOverflow;)
Fredrik A.
34

Voici une fonction appelée ucfirst () (abréviation de "majuscule première lettre"):

function ucfirst(str) {
    var firstLetter = str.substr(0, 1);
    return firstLetter.toUpperCase() + str.substr(1);
}

Vous pouvez mettre une chaîne en majuscule en appelant ucfirst ("une chaîne") - par exemple,

ucfirst("this is a test") --> "This is a test"

Il fonctionne en divisant la chaîne en deux morceaux. Sur la première ligne, il extrait firstLetter , puis sur la deuxième ligne, il capitalise firstLetter en appelant firstLetter.toUpperCase () et le joint au reste de la chaîne, qui est trouvé en appelant str.substr (1) .

Vous pourriez penser que cela échouerait pour une chaîne vide, et en effet, dans un langage comme C, vous devrez répondre à cela. Cependant, en JavaScript, lorsque vous prenez une sous-chaîne d'une chaîne vide, vous obtenez simplement une chaîne vide.

Robert Wills
la source
4
Utilisez String.substring () ou String.slice () ... N'utilisez pas substr () - c'est obsolète.
James
7
@ 999: où est-il dit que substr()c'est obsolète? Ce n'est pas , même maintenant, trois ans plus tard, encore moins en 2009 lorsque vous avez fait ce commentaire.
Dan Dascalescu
substr()peut ne pas être marqué comme déconseillé par une implémentation ECMAScript populaire (je doute que cela ne disparaisse pas de si tôt), mais cela ne fait pas partie de la spécification ECMAScript. La 3e édition de la spécification le mentionne dans l'annexe non normative afin de "suggérer une sémantique uniforme pour ces propriétés sans faire des propriétés ou de leur sémantique une partie de cette norme".
Peter Rust
2
Avoir 3 méthodes qui font la même chose ( substring, substret slice), c'est trop, OMI. J'utilise toujours sliceparce qu'il prend en charge les index négatifs, il n'a pas le comportement de permutation d'arguments déroutant et son API est similaire à slicedans d'autres langues.
Peter Rust
29
String.prototype.capitalize = function(){
    return this.replace( /(^|\s)([a-z])/g , function(m,p1,p2){ return p1+p2.toUpperCase();
    } );
};

Usage:

capitalizedString = someString.capitalize();

Ceci est une chaîne de texte => Ceci est une chaîne de texte

Murat Kucukosman
la source
20
Les expressions régulières sont exagérées pour cela.
Anthony Sottile
+1, c'est ce que je cherchais vraiment. Il y a cependant un bug mineur, il devrait être return.this.toLocaleLowerCase().replace(...
tomdemuyt
+1, J'ai trouvé cette page à la recherche d'une version javascript de phps ucfirst, ce qui, je pense, est la façon dont la plupart des gens la trouvent.
Benubird
@DanDascalescu J'ai trouvé cela utile, donc +1 utilitarisme et -1 rétention anale. Il a inclus un exemple, donc sa fonction est claire.
Travis Webb
String.prototype.capitalize = function(){ return this.replace( /(^|\s)[a-z]/g , function(m){ return m.toUpperCase(); }); }; Je refaçonne un peu votre code, vous n'avez besoin que d'une première correspondance.
IGRACH
28
var str = "test string";
str = str.substring(0,1).toUpperCase() + str.substring(1);
MaxEcho
la source
21

Découvrez cette solution:

var stringVal = 'master';
stringVal.replace(/^./, stringVal[0].toUpperCase()); // returns Master 
Raju Bera
la source
3
Ce devrait être la réponse acceptée. La solution principale ne devrait pas utiliser un framework comme le soulignement.
Adam McArthur
3
Économisez quelques touches;)stringVal.replace(/^./, stringVal[0].toUpperCase());
Alfredo Delgado
1
Regex ne doit pas être utilisé lorsque cela n'est pas nécessaire. C'est très inefficace et cela ne rend pas le code plus concis non plus. De plus, ce stringVal[0]serait undefinedpour vide stringVal, et en tant que tel, tenter d'accéder à la propriété .toUpperCase()jetterait une erreur.
Przemek
20
yourString.replace(/^[a-z]/, function(m){ return m.toUpperCase() });

(Vous pouvez l'encapsuler dans une fonction ou même l'ajouter au prototype String si vous l'utilisez fréquemment.)

Simon
la source
5
Même si cela a pas mal de votes, c'est de loin la solution la plus lente publiée ici. J'ai mis en place un petit speedtest avec les réponses les plus populaires de ce post, ici: forwebonly.com/…
Robin van Baalen
@RobinvanBaalen Votre lien est maintenant rompu. Vous en avez une mise à jour?
Brad
1
Regexp est exagéré pour cela, préférez le plus simple: str.charAt (0) .toUpperCase () + str.slice (1)
Simon
@Brad malheureusement pas
Robin van Baalen
Souvent, si vous voulez résoudre votre problème avec l'expression régulière, vous vous retrouvez avec deux problèmes.
Przemek
19

La ucfirstfonction fonctionne si vous le faites comme ça.

function ucfirst(str) {
    var firstLetter = str.slice(0,1);
    return firstLetter.toUpperCase() + str.substring(1);
}

Merci JP pour cette déclaration.

raphie
la source
2
joli nom pour la fonction! Son nom est identique à l'équivalent PHP. Il existe en fait une bibliothèque complète de fonctions PHP écrites en JS; il s'appelle PHP.js et se trouve sur http://phpjs.org
Hussam
11
Un paquebot:string[0].toUpperCase() + string.substring(1)
dr.dimitru
@TarranJones ici est à l'épreuve des balles:(string[0] || '').toUpperCase() + string.substring(1)
dr.dimitru
@ dr.dimitru: Au lieu d'idiomatique, (string[0] || '')vous pourriez tout simplement string.charAt(0).
Przemek
18

Vous pouvez le faire en une seule ligne comme celle-ci

string[0].toUpperCase() + string.substring(1)
Qwerty
la source
Cette réponse a déjà été donnée en 2009 .
Dan Dascalescu
17
yourString.replace(/\w/, c => c.toUpperCase())

J'ai trouvé cette fonction de flèche la plus simple. Remplacer correspond au premier caractère de lettre ( \w) de votre chaîne et le convertit en majuscule. Rien de plus sophistiqué nécessaire.

Loup
la source
1
Cela devrait être la réponse acceptée, mais c'est presque la dernière, car SO continue d'attribuer des questions obsolètes. Btw, il vaut mieux utiliser /./pour deux raisons: /\w/sautera tous les caractères précédents non-lettre (donc @@ abc deviendra @@ Abc), puis cela ne fonctionnera pas avec les caractères non latins
Cristian Traìna