Come posso rendere maiuscola la prima lettera di una stringa in JavaScript?


3763

Come posso rendere maiuscola la prima lettera di una stringa, ma non cambiare il caso di nessuna delle altre lettere?

Per esempio:

  • "this is a test" -> "This is a test"
  • "the Eiffel Tower" -> "The Eiffel Tower"
  • "/index.html" -> "/index.html"

12
Underscore ha un plugin chiamato underscore.string che include questo e un sacco di altri fantastici strumenti.
Aaron,

che dire:return str.replace(/(\b\w)/gi,function(m){return m.toUpperCase();});
Muhammad Umer del

111
string[0].toUpperCase() + string.substring(1)
Più

7
`${s[0].toUpperCase()}${s.slice(1)}`
noego,

([initial, ...rest]) => [initial.toUpperCase(), ...rest].join("")
Константин Ван

Risposte:


5811

La soluzione di base è:

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

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

Alcune altre risposte modificano String.prototype(anche questa era una risposta), ma sconsiglio ora questo a causa della manutenibilità (difficile da scoprire dove la funzione viene aggiunta a prototypee potrebbe causare conflitti se un altro codice utilizza lo stesso nome / un browser aggiunge una funzione nativa con lo stesso nome in futuro).

... e poi, c'è molto di più in questa domanda quando si considera l'internazionalizzazione, come dimostra questa risposta sorprendentemente buona (sepolta sotto).

Se si desidera lavorare con punti di codice Unicode anziché unità di codice (ad esempio per gestire i caratteri Unicode al di fuori del piano multilingue di base) è possibile sfruttare il fatto che String#[@iterator]funziona con i punti di codice e si può usare toLocaleUpperCaseper ottenere maiuscole corrette a livello locale:

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!)

Per ulteriori opzioni di internazionalizzazione, vedere la risposta originale di seguito .


9
substring è compreso in più browser rispetto a substr
mplungjan,

6
da aggiungere a karim79 - probabilmente è eccessivo per renderlo una funzione in quanto javascript farà la stessa cosa con la variabile senza il wrapping della funzione. Suppongo che sarebbe più chiaro usando una funzione, ma è nativo altrimenti, perché complicarlo con un wrapper di funzioni?
Ross,

18
Non dovremmo anche LowerCase the slice (1)?
hasen

177
No, perché l'OP ha fatto questo esempio: the Eiffel Tower -> The Eiffel Tower. In più, la funzione viene chiamata capitaliseFirstLetternon capitaliseFirstLetterAndLowerCaseAllTheOthers.
divieto di geoingegneria

22
A nessuno importa dell'importante regola dell'OOP? - Non modificare mai oggetti che non possiedi? . A proposito, questo one-liner sembra molto più elegante:string[0].toUpperCase() + string.substring(1)
dr.dimitru

1350

Ecco un approccio più orientato agli oggetti:

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

Chiameresti la funzione in questo modo:

"hello world".capitalize();

Con l'output previsto essere:

"Hello world" 

24
Mi piace questa soluzione perché è come Ruby e Ruby è dolce! :) Ho minuscole tutte le altre lettere della stringa in modo che funzioni esattamente come Ruby:return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
ma11hew28

164
In questo mondo post-Prototype.js, non è consigliabile modificare o estendere gli oggetti nativi.
Ryan,

191
@rxgx - Il boogeyman "non estendere" ora sta iniziando a scomparire (grazie a dio), e le persone stanno tirando fuori la testa da jSand e realizzando che è solo una caratteristica del linguaggio. Solo perché Prototype.js ha esteso l'oggetto stesso per un breve periodo, non significa che l'estensione dei nativi sia un male. Non dovresti farlo se stai scrivendo codice per un consumatore sconosciuto (come uno script di analisi che va su siti casuali), ma a parte questo va bene.
csuwldcat,

43
@csuwldcat E se un'altra libreria che stai usando aggiunge il suo maiuscolo senza che tu lo sappia? L'estensione dei prototipi è una cattiva forma, indipendentemente dal fatto che Prototype.js lo abbia fatto o meno. Con ES6, i prodotti intrinseci ti permetteranno di mangiare e mangiare anche la tua torta. Penso che potresti confondere il "boogeyman" morire per le persone che creano spessori conformi alle specifiche ECMASCRIPT. Questi spessori vanno benissimo perché un'altra libreria che ha aggiunto uno spessore lo implementerebbe allo stesso modo. Tuttavia, è necessario evitare di aggiungere i propri intrinseci non specifici.
Justin Meyer,

43
L'estensione dei nativi è una cattiva pratica ESTREMAMENTE. Anche se dici "oh, non userò mai questo codice con nient'altro", tu (o qualcun altro) probabilmente lo farai. Trascorreranno quindi tre giorni cercando di capire qualche strano bug matematico perché qualcuno ha esteso Number.money () per gestire una valuta leggermente diversa dall'altra libreria. Scherzi a parte, l'ho visto accadere in una grande azienda e non vale la pena fare il debug a nessuno per capire se uno sviluppatore di biblioteche ha fatto casino con i prototipi dei nativi.
phreakhead il

574

Nel CSS:

p:first-letter {
    text-transform:capitalize;
}

80
OP richiede una soluzione JS.
Antonio Max,

129
. $ ( '# mystring_id') testo (stringa) css ( 'text-transform', 'capitalizzare');
DonMB,

21
Inoltre, ciò influisce solo sulla visualizzazione della stringa, non sul valore effettivo. Se è in una forma, ad esempio, il valore verrà comunque inviato così com'è.
Dmansfield,

12
Questa risposta mi ha aiutato a capire che una soluzione CSS era davvero più appropriata per quello che stavo facendo. @dudewad: la risposta probabilmente dovrebbe dare un disclaimer sul fatto che questa non è una soluzione JS ma potrebbe essere più appropriata a seconda delle necessità.
joshden,

58
Per circa l'80% degli spettatori che arrivano a questa domanda, questa sarà la risposta migliore. Non una risposta alla domanda , ma invece al problema .
Jivan,

290

Ecco una versione abbreviata della risposta popolare che ottiene la prima lettera trattando la stringa come un array:

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

Aggiornare:

Secondo i commenti qui sotto questo non funziona in IE 7 o sotto.

Aggiornamento 2:

Per evitare undefinedstringhe vuote (vedere il commento di @ njzk2 di seguito ), è possibile verificare la presenza di una stringa vuota:

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

23
Questo non funzionerà in IE <8, poiché quei browser non supportano l'indicizzazione delle stringhe. Lo stesso IE8 lo supporta, ma solo per i letterali di stringa, non per gli oggetti di stringa.
Mathias Bynens,

52
chi se ne frega, il mercato IE7 è inferiore al 5%! e quelli sono probabilmente la vecchia macchina di tuo gremma e grempa. Dico il codice breve FTW!
vsync,

@MathiasBynens Sai se questo influisce su browser non IE precedenti o solo su IE7? Se nessun altro browser è interessato dall'indicizzazione dei valori letterali delle stringhe nel 2014, dovremmo andare bene. :)
hexalys,

3
@vsync Volevo solo dire che, a seconda dei dati demografici degli utenti, a volte (anche se con gratitudine sempre meno mentre passiamo il 2014 e oltre) è vantaggioso supportare vecchi browser come IE7 ...
joshuahedlund

2
@ njzk2 per gestire una stringa vuota, è possibile aggiornare a questo: return s && s[0].toUpperCase() + s.slice(1);
joelvh

188

Se sei interessato all'esecuzione di alcuni diversi metodi pubblicati:

Ecco i metodi più veloci basati su questo test jsperf (ordinato dal più veloce al più lento).

Come puoi vedere, i primi due metodi sono sostanzialmente comparabili in termini di prestazioni, mentre l'alterazione String.prototypeè di gran lunga la più lenta in termini di prestazioni.

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

inserisci qui la descrizione dell'immagine


1
Sembra che neanche il codice di inizializzazione faccia la differenza: jsperf.com/capitalize-first-letter-of-string/2
user420667

6
Si noti inoltre che la sostituzione .slice(1)con .substr(1)migliorerebbe ulteriormente le prestazioni.
Przemek,

2
Considerazione ragionevole. Tenete presente che in molti casi il colpo di prestazione non è nemmeno evidente: anche l'approccio "più lento" gestirà stringhe 19k in 10 ms. Quindi prendi quello più comodo da usare per te.
Citando Eddie il

1
Nel caso in cui qualcuno sia curioso (come me) di come le prestazioni di questo siano aumentate negli ultimi quattro anni, le operazioni al secondo della terza funzione su un macbook pro 2018 sono a 135.307.869, quindi sostanzialmente 12,4 volte più veloci.
Carlo Field,

151

Per un altro caso ne ho bisogno per scrivere in maiuscolo la prima lettera e minuscole per il resto. I seguenti casi mi hanno fatto cambiare questa funzione:

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

1
"... ma non cambiare il caso di nessuna delle altre lettere". Questa non è una risposta corretta alla domanda posta dall'OP.
Carlos Muñoz,

2
@ CarlosMuñoz se leggi la frase di apertura dice che è per un caso diverso.
TMH,

3
@TomHart Questo è esattamente il motivo per cui non è una soluzione alla domanda. Dovrebbe essere un commento o un'altra domanda e risposta
Carlos Muñoz,

15
Sono d'accordo con te su questo, ma posso vedere molte persone che finiscono qui cercando di fare quello che fa questa risposta.
TMH,

74

Questa è la soluzione 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


5
.slice()è più lento di .substring(), str[0]sarebbe undefinedper una stringa vuota e l'uso dei letterali template per unire le due parti introduce qui 8 caratteri, mentre +introdurrebbe solo 3.
Przemek

4
Il punto della mia risposta Prz è mostrare le nuove funzionalità supportate da ES6, in particolare i letterali dei template che non sono stati menzionati in altri post. L'idea di StackOverflow è di dare al ricercatore “opzioni”. Possono prendere il concetto di Template Literals descritto in questa risposta e combinarlo con miglioramenti della micro-velocità come Substring v. Slice se la loro applicazione richiede quei millisecondi risparmiati in più. La mia risposta, inoltre, non include alcun test unitario, il che dimostra che non dovresti mai copiare direttamente una risposta StackOverflow. Presumo che lo sviluppatore prenderà la mia risposta e la adatterà.
Sterling Bourne,

Non ottieni nulla dall'uso dei letterali modello qui e il ${}solo aggiunge rumore. const newStr = str[0].toUpperCase() + str.slice(1);è più facile da leggere.
Boris,

1
Accetta di non essere d'accordo su ciò che è più facile da leggere.
Sterling Bourne,

67

Se stai già (o considerando) l'utilizzo lodash, la soluzione è semplice:

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

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

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

Vedi i loro documenti: 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 per la prima maiuscola:

function upperCaseFirst(str){
    return str.charAt(0).toUpperCase() + str.substring(1);
}

11
Penso che la preferenza dovrebbe essere per J vaniglia poiché la maggior parte delle persone non scaricherà un intero framework solo per capitalizzare una stringa.
GGG,

7
Finora non ho mai usato lodash in tutti i miei progetti. Non dimenticare che la maggior parte delle persone su Google finirà in questa pagina e elencare un framework come alternativa va bene, ma non come risposta principale.
GGG

2
Dato che altre risposte usano vanilla js, è bello avere una risposta come questa, dato che molti di noi usano lodash / underscore.
Lu Roman,

1
Questa non è la risposta corretta poiché l'OP chiede ora di farlo in Javascript, non in una libreria Javascript, che importa un'intera libreria come dipendenza per il progetto. Non usarlo.
Dudewad,

1
La domanda del PO è in vaniglia alla fine della mia risposta.
amante il

62

Scrivi in ​​maiuscolo la prima lettera di tutte le parole in una stringa:

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(" ");
}

14
Rileggere la domanda: voglio scrivere in maiuscolo il primo carattere di una stringa, ma non cambiare il caso di nessuna delle altre lettere.
JimmyPena,

2
So di averlo fatto. Aggiungerei una cosa, nel caso in cui l'intera stringa inizi in maiuscolo: pieces [i] = j + pieces [i] .substr (1) .toLowerCase ();
Malovich,

4
Un'altra soluzione a questo caso: funzione capitaliseFirstLetters (s) {return s.split ("") .map (function (w) {return w.charAt (0) .toUpperCase () + w.substr (1)}). ("")} Può essere una bella riga se non viene messa in funzione.
Luke Channings

Sarebbe meglio prima minuscolare l'intera stringa
Magico

Oltre a questa funzione che non risponde alla domanda, in realtà è anche troppo complicata. s => s.split(' ').map(x => x[0].toUpperCase() + x.slice(1)).join(' ')
OverCoder,

48

Potremmo ottenere il primo personaggio con uno dei miei preferiti RegExp, sembra una faccina carina:/^./

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

E per tutti i drogati di caffè:

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

... e per tutti i ragazzi che pensano che ci sia un modo migliore per farlo, senza estendere i prototipi nativi:

var capitalize = function (input) {
  return input.replace(/^./, function (match) {
    return match.toUpperCase();
  });
};

2
C'è un modo migliore per farlo senza modificare il prototipo String.
Big McLarge: enorme

2
@ davidkennedy85 Certo! Ma questo è il modo semplice, non il modo migliore ... ;-)
yckart

Caro signore, ci sono milioni di risposte a questa domanda! La tua soluzione sembra ancora più bella in es6. 'Answer'.replace(/^./, v => v.toLowerCase())
stwilz,

47

Uso:

var str = "ruby java";

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

Verrà emesso "Ruby java"sulla console.


Una soluzione di linea.
Ahmad Sharif,

45

Se usi underscore.js o Lo-Dash , la libreria underscore.string fornisce estensioni di stringa, tra cui maiuscole:

_.capitalize (stringa) Converte la prima lettera della stringa in maiuscolo.

Esempio:

_.capitalize("foo bar") == "Foo bar"

3
Dalla versione 3.0.0 , Lo-Dash ha questo metodo stringa disponibile per impostazione predefinita. Proprio come descritto in questa risposta: _.capitalize("foo") === "Foo".
bardzusny,

Inoltre ci sono utili funzioni underscore.js chiamate humanize. Converte una stringa sottolineata, cammellata o divelizzata in una stringa umanizzata. Rimuove anche gli spazi iniziali e finali e rimuove il postfisso '_id'.
Stepan Zakharov,

1
Dalla versione 4 *, anche Lodash minuscola () ogni altra lettera, fai attenzione!
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
}

E poi:

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

Aggiornamento novembre 2016 (ES6), solo per DIVERTIMENTO:

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

poi capitalize("hello") // Hello


3
Penso che questa sia una soluzione scadente per 2 motivi: modificare il prototipo di una primitiva è una cattiva idea. Se le specifiche cambiano e decidono di selezionare "capitalizza" come nuovo nome di proprietà proto, stai rompendo la funzionalità del linguaggio di base. Inoltre, il nome del metodo scelto è scadente. A prima vista, penso che questo capitalizzerà l'intera stringa. Usare un nome più descrittivo come ucFirst di PHP o qualcosa di simile potrebbe essere un'idea migliore.
Dudewad,

L'altra risposta ES6 è più semplice: const capitalize = ([first,...rest]) => first.toUpperCase() + rest.join('').toLowerCase();.
Dan Dascalescu il

44

Le soluzioni più brevi 3, 1 e 2 gestiscono i casi quando la sstringa è ""e nulle 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


42

Solo CSS

p::first-letter {
  text-transform: uppercase;
}
  • Nonostante sia chiamato ::first-letter, si applica al primo carattere , ovvero in caso di stringa %a, questo selettore si applicherebbe %e come tale anon verrebbe maiuscolo.
  • In IE9 + o IE5.5 + è supportato nella notazione legacy con solo due punti ( :first-letter).

ES2015 one-liner

Dato che ci sono numerose risposte, ma nessuna in ES2015 che avrebbe risolto il problema originale in modo efficiente, ho trovato quanto segue:

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

Osservazioni

  • parameters => functionè la cosiddetta funzione freccia .
  • Ho scelto capitalizeFirstCharinvece il nome capitalizeFirstLetter, perché OP non ha richiesto il codice che mette in maiuscolo la prima lettera dell'intera stringa, ma il primo carattere (se si tratta di lettere, ovviamente).
  • constci dà la possibilità di dichiarare capitalizeFirstCharcome costante, il che è desiderato poiché come programmatore dovresti sempre dichiarare esplicitamente le tue intenzioni.
  • Nel benchmark che ho eseguito non c'erano differenze significative tra string.charAt(0)e string[0]. Si noti, tuttavia, che string[0]sarebbe undefinedper stringa vuota, quindi dovrebbe essere riscritto string && string[0], che è troppo prolisso, rispetto all'alternativa.
  • string.substring(1)è più veloce di string.slice(1).

Prova delle prestazioni

  • 4.956.962 ops / s ± 3,03% per questa soluzione,
  • 4.577.946 ops / s ± 1,2% per la risposta più votata.
  • Creato con JSBench.me su Google Chrome 57.

Confronto tra soluzioni


@Verde: , sei sicuro di aver specificato il selettore con due punti?
Przemek,

1
In realtà non si desidera utilizzare il segno più (+) come metodo di concatenazione in ES6. Ti consigliamo di utilizzare i template letterali: eslint.org/docs/rules/prefer-template
Sterling Bourne

42

C'è un modo molto semplice per implementarlo sostituendolo . Per ECMAScript 6:

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

Risultato:

'Foo'

1
La migliore risposta di gran lunga, e punti extra per mostrare la sintassi regex lambda. Mi piace soprattutto questo in quanto può essere un incollabile ovunque.
Wade Hatler,

L'uso /^[a-z]/isarà migliore dell'uso .poiché il precedente non proverà a sostituire nessun carattere diverso dagli alfabeti
Codice Maniac

39

Non ho visto alcuna menzione nelle risposte esistenti di problemi relativi ai punti di codice del piano astrale o all'internazionalizzazione . "Maiuscolo" non significa la stessa cosa in ogni lingua usando un determinato script.

Inizialmente non ho visto alcuna risposta per risolvere i problemi relativi ai punti di codice del piano astrale. Ce n'è uno , ma è un po 'sepolto (come questo, immagino!)


La maggior parte delle funzioni proposte è simile a questa:

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

Tuttavia, alcuni caratteri racchiusi non rientrano nel BMP (piano multilingue di base, punti codice da U + 0 a U + FFFF). Ad esempio prendi questo testo Deseret:

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

Il primo carattere qui non riesce a scrivere in maiuscolo perché le proprietà delle stringhe indicizzate in array non accedono a "caratteri" o punti di codice *. Accedono alle unità di codice UTF-16. Questo vale anche durante lo slicing: i valori dell'indice puntano su unità di codice.

Capita che le unità di codice UTF-16 siano 1: 1 con punti di codice USV entro due intervalli, da U + 0 a U + D7FF e da U + E000 a U + FFFF inclusi. La maggior parte dei personaggi racchiusi in questi due range, ma non tutti.

Da ES2015 in poi, affrontarlo è diventato un po 'più semplice. String.prototype[@@iterator]restituisce stringhe corrispondenti a punti di codice **. Quindi, ad esempio, possiamo fare questo:

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

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

Per stringhe più lunghe, questo probabilmente non è terribilmente efficiente *** - non abbiamo davvero bisogno di ripetere il resto. Potremmo usare String.prototype.codePointAtper arrivare a quella prima (possibile) lettera, ma dovremmo ancora determinare da dove dovrebbe iniziare la sezione. Un modo per evitare di ripetere il resto sarebbe verificare se il primo punto di codice è esterno al BMP; in caso contrario, la sezione inizia da 1 e, in caso affermativo, la sezione inizia da 2.

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

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

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

Potresti usare la matematica bit a bit invece di > 0xFFFFlì, ma probabilmente è più facile da capire in questo modo e raggiungerebbe la stessa cosa.

Possiamo anche farlo funzionare in ES5 e in basso, portando questa logica un po 'più in là, se necessario. Non esistono metodi intrinseci in ES5 per lavorare con i punti di codice, quindi dobbiamo testare manualmente se la prima unità di codice è un surrogato ****:

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("𐐶𐐲𐑌𐐼𐐲𐑉") // "𐐎𐐲𐑌𐐼𐐲𐑉"

All'inizio ho citato anche considerazioni sull'internazionalizzazione. Alcuni di questi sono molto difficili da conto perché richiedono la conoscenza non solo di ciò che è in uso la lingua, ma anche possono richiedere conoscenze specifiche delle parole nella lingua. Ad esempio, il digraph irlandese "mb" capitalizza come "mB" all'inizio di una parola. Un altro esempio, il tedesco eszett, non inizia mai una parola (afaik), ma aiuta ancora a illustrare il problema. Il minuscolo eszett ("ß") diventa "SS", ma "SS" può minuscolare in "ß" o "ss" - è necessaria una conoscenza fuori banda della lingua tedesca per sapere quale sia corretta!

L'esempio più famoso di questo tipo di problemi, probabilmente, è il turco. In latino turco, la forma maiuscola di I è İ, mentre la forma minuscola di I è ı - sono due lettere diverse. Fortunatamente abbiamo un modo per rendere conto di questo:

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

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

In un browser, il tag della lingua più preferita dell'utente è indicato da navigator.language, un elenco in ordine di preferenza è disponibile all'indirizzo navigator.languagese la lingua di un determinato elemento DOM può essere ottenuta (di solito) con Object(element.closest('[lang]')).lang || YOUR_DEFAULT_HEREdocumenti in più lingue .

Negli agenti che supportano le classi di caratteri delle proprietà Unicode in RegExp, introdotte in ES2018, possiamo ripulire ulteriormente le cose esprimendo direttamente quali caratteri ci interessano:

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

Questo potrebbe essere modificato un po 'per gestire anche la maiuscola di più parole in una stringa con una precisione abbastanza buona. Il CWUo proprietà del carattere Changes_When_Uppercased corrisponde a tutti i punti di codice che, bene, cambiano quando vengono maiuscoli. Possiamo provarlo con un personaggio digraph titolato come l'olandese ij per esempio:

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

Al momento della stesura (febbraio 2020), Firefox / Spidermonkey non ha ancora implementato nessuna delle funzionalità RegExp introdotte negli ultimi due anni *****. Puoi controllare lo stato corrente di questa funzione nella tabella di compatibilità Kangax . Babel è in grado di compilare letterali RegExp con riferimenti di proprietà a schemi equivalenti senza di essi, ma sii consapevole che il codice risultante potrebbe essere enorme.


Con ogni probabilità, le persone che pongono questa domanda non si occuperanno di capitalizzazione o internazionalizzazione del Deseret. Ma è bene essere consapevoli di questi problemi perché c'è una buona probabilità che li incontri alla fine anche se al momento non sono preoccupazioni. Non sono casi "marginali", o meglio, non lo sono casi limite per definizione - c'è un intero paese in cui la maggior parte delle persone parla turco, e comunque, la fusione di unità di codice con punti di codice è una fonte abbastanza comune di bug (specialmente con riguardo alle emoji). Sia le stringhe che il linguaggio sono piuttosto complicati!


* Le unità di codice di UTF-16 / UCS2 sono anche punti di codice Unicode, nel senso che ad esempio U + D800 è tecnicamente un punto di codice, ma non è quello che "significa" qui ... in un certo senso ... anche se diventa piuttosto sfocata. Ciò che i surrogati sicuramente non sono, tuttavia, sono USV (valori scalari Unicode).

** Tuttavia, se un'unità di codice surrogato è “orfana”, ovvero non fa parte di una coppia logica, è possibile ottenere anche surrogati qui.

*** può essere. Non l'ho provato. A meno che tu non abbia determinato che la capitalizzazione è un collo di bottiglia significativo, probabilmente non lo farei sudare: scegli quello che ritieni più chiaro e leggibile.

**** tale funzione potrebbe voler testare sia la prima che la seconda unità di codice anziché solo la prima, poiché è possibile che la prima unità sia un surrogato orfano. Ad esempio, l'ingresso "\ uD800x" renderebbe maiuscola la X così com'è, cosa che può o non può essere prevista.

***** Ecco il problema Bugzilla se vuoi seguire i progressi più direttamente.


2
Questa risposta deve essere spostata in primo piano.
Rúnar Berg,

Grazie @ RúnarBerg - poiché il tuo commento mi ha ricordato questo, ho letto di nuovo su di esso e mi sono reso conto che avevo lasciato fuori un caso finale e una soluzione che vale la pena menzionare. Ho anche cercato di chiarire meglio una parte della terminologia.
Punto

Ottima risposta .....
Ben Aston,

Questa risposta è eccellente, vorrei poter votare di più.
David Barker,

38

Sembra essere più facile nei CSS:

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

Questo proviene dalla proprietà di trasformazione del testo CSS (su W3Schools ).


29
@Simon Non si afferma che la stringa verrà necessariamente emessa come parte di un documento HTML - CSS sarà utile solo se lo è.
Adam Hepton,

9
Adam, vero, ma immagino che oltre il 95% di Javascript sia utilizzato con HTML e CSS. Sfortunatamente, l'istruzione "capitalize" in realtà capitalizza ogni parola , quindi avresti ancora bisogno di JS per scrivere in maiuscolo solo la prima lettera della stringa.
Simon East,

18
Errato, Dinesh. Ha detto il primo carattere della stringa .
Simon East,

81
Questa risposta, nonostante abbia un numero ridicolo di voti, è semplicemente sbagliata, poiché capitalizzerà la prima lettera di ogni parola. @Ryan, guadagnerai un badge disciplinato se lo elimini. Per favore fallo.
Dan Dascalescu il

10
Concordo con @DanDascalescu: la risposta di Ryan è completamente sbagliata.
Timo,

38
var capitalized = yourstring[0].toUpperCase() + yourstring.substr(1);

37

È sempre meglio gestire prima questo tipo di cose usando i CSS , in generale, se puoi risolvere qualcosa usando i CSS, prova prima, quindi prova JavaScript per risolvere i tuoi problemi, quindi in questo caso prova a usare :first-letterCSS e applicatext-transform:capitalize;

Quindi prova a creare una classe per questo, in modo da poterla utilizzare a livello globale, ad esempio: .first-letter-uppercasee aggiungi qualcosa come sotto nel tuo CSS:

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

Anche l'opzione alternativa è JavaScript, quindi il migliore sarà qualcosa del genere:

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

e chiamalo come:

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'

Se vuoi riutilizzarlo più e più volte, è meglio collegarlo alla stringa nativa javascript, quindi qualcosa di simile al seguente:

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

e chiamalo come di seguito:

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

36

Se si desidera riformattare il testo in maiuscolo, è possibile modificare gli altri esempi in quanto tali:

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

Questo assicurerà che il seguente testo sia cambiato:

TEST => Test
This Is A TeST => This is a test

Probabilmente vale la pena notare che questo convertirà anche cose come gli acronimi in minuscolo, quindi forse non la migliore idea nella maggior parte dei casi
monokrome

Inoltre, GAMITG ha davvero apportato una modifica solo per rimuovere un pezzo di spazio bianco da una parte non di codice del post? O_O
monokrome,

tra l'altro, questo romperà gli acronimi maiuscoli quindi state attenti a tutti <3
monokrome

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'

Fatto @Ram. Sono inclusi anche esempi.
Fredrik A.,

In che modo è migliore della risposta del 2009 ?
Dan Dascalescu,

1
Non è @DanDascalescu. Suppongo che potresti sostenere che substr/ substringè un po 'più semantico rispetto a slice, ma è solo una questione di preferenza. Ho comunque incluso esempi con le stringhe fornite nella domanda, il che è un bel tocco non presente nell'esempio '09. Sinceramente penso che si riduca a 15 anni che voglio il karma su StackOverflow;)
Fredrik A.

34

Ecco una funzione chiamata ucfirst () (abbreviazione di "maiuscola prima lettera"):

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

Puoi capitalizzare una stringa chiamando ucfirst ("una stringa") , ad esempio,

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

Funziona dividendo la stringa in due pezzi. Sulla prima riga estrae firstLetter e poi sulla seconda riga capitalizza firstLetter chiamando firstLetter.toUpperCase () e lo unisce al resto della stringa, che si trova chiamando str.substr (1) .

Potresti pensare che questo fallirebbe per una stringa vuota, e in effetti in un linguaggio come C dovresti provvedere a questo. Tuttavia in JavaScript, quando si prende una sottostringa di una stringa vuota, si ottiene semplicemente una stringa vuota indietro.


4
Usa String.substring () o String.slice () ... Non usare substr () - è obsoleto.
James,

7
@ 999: dove dice che substr()è deprecato? Tre anni dopo, non è nemmeno tornato, per non parlare del 2009, quando hai fatto questo commento.
Dan Dascalescu il

substr()potrebbe non essere contrassegnato come deprecato da qualsiasi implementazione ECMAScript popolare (dubito che non scomparirà presto), ma non fa parte delle specifiche ECMAScript. La terza edizione della specifica la menziona in allegato non normativo al fine di "suggerire una semantica uniforme per tali proprietà senza rendere le proprietà o la loro semantica parte di questo standard".
Peter Rust,

2
Avere 3 metodi che fanno la stessa cosa ( substring, substre slice) è troppi, IMO. Uso sempre sliceperché supporta indici negativi, non ha il comportamento confuso di scambio di argomenti e la sua API è simile slicein altre lingue.
Peter Rust,

29
String.prototype.capitalize = function(){
    return this.replace( /(^|\s)([a-z])/g , function(m,p1,p2){ return p1+p2.toUpperCase();
    } );
};

Uso:

capitalizedString = someString.capitalize();

Questa è una stringa di testo => Questa è una stringa di testo


20
Le espressioni regolari sono eccessive per questo.
Anthony Sottile,

+1, questo è quello che stavo davvero cercando. C'è un piccolo bug però, dovrebbe essere return.this.toLocaleLowerCase().replace(...
tomdemuyt,

+1, ho trovato questa pagina alla ricerca di una versione javascript di phps prima di tutto, che sospetto sia come la maggior parte delle persone la trova.
Benubird,

@DanDascalescu L'ho trovato utile, quindi +1 utilitarismo e -1 ritenzione anale. Ha incluso un esempio, quindi la sua funzione è chiara.
Travis Webb,

String.prototype.capitalize = function(){ return this.replace( /(^|\s)[a-z]/g , function(m){ return m.toUpperCase(); }); }; Riformo un po 'il tuo codice, hai solo bisogno di una prima corrispondenza.
IGRACH,

28
var str = "test string";
str = str.substring(0,1).toUpperCase() + str.substring(1);

21

Dai un'occhiata a questa soluzione:

var stringVal = 'master';
stringVal.replace(/^./, stringVal[0].toUpperCase()); // returns Master 

3
Questa dovrebbe essere la risposta accettata. La soluzione principale non dovrebbe usare un framework come il trattino basso.
Adam McArthur,

3
Salva alcuni tasti;)stringVal.replace(/^./, stringVal[0].toUpperCase());
Alfredo Delgado,

1
Regex non dovrebbe essere usato dove non necessario. È molto inefficiente e non rende neanche il codice più conciso. Inoltre, stringVal[0]sarebbe undefinedvuoto stringVal, e come tale tentativo di accedere alla proprietà .toUpperCase()genererebbe un errore.
Przemek,

20
yourString.replace(/^[a-z]/, function(m){ return m.toUpperCase() });

(È possibile incapsularlo in una funzione o addirittura aggiungerlo al prototipo String se lo si utilizza frequentemente.)


5
Anche se questo ha parecchi voti, questa è di gran lunga la soluzione più lenta pubblicata qui. Ho messo insieme un po 'di speedtest con le risposte più popolari di questo post, qui: forwebonly.com/…
Robin van Baalen,

@RobinvanBaalen Il tuo link ora è rotto. Ne hai uno aggiornato?
Brad

1
Regexp è eccessivo per questo, preferisce il più semplice: str.charAt (0) .toUpperCase () + str.slice (1)
Simon

@Brad purtroppo no
Robin van Baalen il

Spesso, se si desidera risolvere il problema con regex, si verificano due problemi.
Przemek,

19

La ucfirstfunzione funziona se lo fai in questo modo.

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

Grazie JP per la dichiarazione.


2
bel nome per la funzione! Il suo nome è identico all'equivalente di PHP. In realtà esiste un'intera libreria di funzioni PHP scritte in JS; si chiama PHP.js e si trova su http://phpjs.org
Hussam l'

11
Una fodera: string[0].toUpperCase() + string.substring(1)
dr.dimitru

@TarranJones qui è un rivestimento antiproiettile: (string[0] || '').toUpperCase() + string.substring(1)
dr.dimitru,

@ dr.dimitru: Invece di idiomatico (string[0] || '')potresti semplicemente string.charAt(0).
Przemek,


17
yourString.replace(/\w/, c => c.toUpperCase())

Ho trovato questa funzione freccia più semplice. Sostituisci corrisponde al carattere della prima lettera ( \w) della stringa e lo converte in maiuscolo. Niente di più elaborato necessario.


1
Questa dovrebbe essere la risposta accettata, invece è quasi l'ultima poiché SO continua a dare domande obsolete. A proposito, è meglio usarlo /./per due motivi: /\w/salterà tutti i precedenti caratteri non lettera (quindi @@ abc diventerà @@ Abc), e quindi non funzionerà con caratteri non latini
Cristian Traìna,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.