Como faço para que a primeira letra de uma string seja maiúscula em JavaScript?

3763

Como faço para que a primeira letra de uma string seja maiúscula, mas não altero o caso de nenhuma das outras letras?

Por exemplo:

  • "this is a test" -> "This is a test"
  • "the Eiffel Tower" -> "The Eiffel Tower"
  • "/index.html" -> "/index.html"
Robert Wills
fonte
12
O Underscore possui um plug-in chamado underscore.string que inclui isso e várias outras ótimas ferramentas.
Aaron
Que tal:return str.replace(/(\b\w)/gi,function(m){return m.toUpperCase();});
Muhammad Umer
111
Mais simples:string[0].toUpperCase() + string.substring(1)
dr.dimitru 25/11
7
`${s[0].toUpperCase()}${s.slice(1)}`
No19
([initial, ...rest]) => [initial.toUpperCase(), ...rest].join("")
Константин Ван

Respostas:

5811

A solução básica é:

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

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

Algumas outras respostas são modificadas String.prototype(essa resposta também costumava ser), mas eu não recomendaria isso agora, devido à capacidade de manutenção (difícil de descobrir onde a função está sendo adicionada prototypee pode causar conflitos se outro código usar o mesmo nome / navegador) adiciona uma função nativa com o mesmo nome no futuro).

... e, então, há muito mais nessa questão quando você considera a internacionalização, como mostra essa resposta surpreendentemente boa (enterrada abaixo).

Se você deseja trabalhar com pontos de código Unicode em vez de unidades de código (por exemplo, para manipular caracteres Unicode fora do Plano Multilíngue Básico), pode aproveitar o fato de que String#[@iterator]funciona com pontos de código e pode usar toLocaleUpperCasepara obter maiúsculas e minúsculas:

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

Para ainda mais opções de internacionalização, consulte a resposta original abaixo .

Steve Harrison
fonte
9
substring é entendido em mais navegadores que substr
mplungjan
6
para adicionar ao karim79 - provavelmente é um exagero torná-lo uma função, pois o javascript fará a mesma coisa com a variável sem a quebra da função. Suponho que seria mais claro o uso de uma função, mas de outra forma nativa, por que complicá-la com um wrapper de função?
Ross
18
Também não deveríamos reduzir a fatia (1)?
hasen
177
Não, porque o OP deu este exemplo: the Eiffel Tower -> The Eiffel Tower. Além disso, a função é chamada capitaliseFirstLetternãocapitaliseFirstLetterAndLowerCaseAllTheOthers .
ban-geoengineering
22
Ninguém se importa com regra importante de OOP? - Nunca edite objetos que você não possui? . BTW, este one-liner parece muito mais elegante:string[0].toUpperCase() + string.substring(1)
dr.dimitru
1350

Aqui está uma abordagem mais orientada a objetos:

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

Você chamaria a função, assim:

"hello world".capitalize();

Com a saída esperada sendo:

"Hello world" 
Steve Hansell
fonte
24
Eu gosto dessa solução porque é como Ruby, e Ruby é doce! :) Eu minúsculas todas as outras letras da string para que funcione exatamente como Ruby:return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
ma11hew28
164
Nesse mundo pós-Prototype.js, não é recomendável alterar ou estender os objetos nativos.
21711 Ryan
191
@rxgx - O bicho-papão "não estenda" está começando a desaparecer (graças a Deus), e as pessoas estão tirando a cabeça do jSand e percebendo que é apenas um recurso de linguagem. Só porque o Prototype.js estendeu o próprio objeto por um breve período, não significa que estender os nativos seja ruim. Você não deve fazê-lo se estiver escrevendo código para um consumidor desconhecido (como um script de análise que vá a sites aleatórios), mas, fora isso, tudo bem.
Csuwldcat 19/05
43
@csuwldcat E se outra biblioteca que você estiver usando adicionar capitalização própria sem que você saiba? Estender protótipos é uma forma incorreta, independentemente de Prototype.js ter feito ou não. Com o ES6, os intrínsecos permitem que você coma seu bolo e também o coma. Eu acho que você pode confundir o "bicho-papão" morrendo por pessoas criando calços que cumprem as especificações do ECMASCRIPT. Esses calços são perfeitamente bons porque outra biblioteca que adicionou um calço o implementaria da mesma maneira. No entanto, adicionar seus próprios intrínsecos não especificados deve ser evitado.
23714 Justin Meyer
43
A extensão de nativos é uma prática extremamente ruim. Mesmo se você disser "oh, eu nunca vou usar esse código com mais nada", você (ou outra pessoa) provavelmente o fará. Depois, eles passarão três dias tentando descobrir algum bug matemático estranho, porque alguém estendeu o Number.money () para lidar com uma moeda ligeiramente diferente da sua outra biblioteca. Sério, eu já vi isso acontecer em uma grande empresa e não vale a pena depurar alguém para descobrir uma biblioteca dev mexida com os protótipos nativos.
phreakhead
574

Em CSS:

p:first-letter {
    text-transform:capitalize;
}
sam6ber
fonte
80
O OP está solicitando uma solução JS.
Antonio Max
129
$ ('# mystring_id'). text (string) .css ('transformação de texto', 'capitalizar');
DonMB 24/09/15
21
Além disso, isso afeta apenas a exibição da string - não o valor real. Se estiver em um formulário, por exemplo, o valor ainda será enviado como está.
dmansfield
12
Essa resposta me ajudou a perceber que uma solução CSS era realmente mais apropriada para o que eu estava fazendo. @dudewad: A resposta provavelmente deve ser um aviso de que esta não é uma solução JS, mas pode ser mais apropriada, dependendo da necessidade.
joshden
58
Para aproximadamente 80% dos espectadores que chegam a esta pergunta, esta será a melhor resposta. Não é uma resposta para a pergunta , mas para o problema .
Jivan
290

Aqui está uma versão abreviada da resposta popular que recebe a primeira letra tratando a string como uma matriz:

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

Atualizar:

De acordo com os comentários abaixo, isso não funciona no IE 7 ou abaixo.

Atualização 2:

Para evitar undefinedseqüências de caracteres vazias (consulte o comentário de @ njzk2 abaixo ), você pode verificar uma sequência de caracteres vazia:

function capitalize(s)
{
    return s && s[0].toUpperCase() + s.slice(1);
}
joelvh
fonte
23
Isso não funcionará no IE <8, pois esses navegadores não suportam indexação de string. O IE8 é compatível com ele, mas apenas para literais de strings - não para objetos de strings.
Mathias Bynens
52
quem se importa, o mercado IE7 é inferior a 5%! e provavelmente essas são as máquinas antigas do seu gremma e do grempa. Eu digo código curto FTW!
vsync
@MathiasBynens Você sabe se isso afeta algum navegador não IE antigo ou apenas o IE7? Se nenhum outro navegador for afetado pela literal de string de indexação em 2014, tudo bem. :)
hexalys
3
@vsync Eu só quis dizer que, dependendo de sua demografia de usuários, às vezes (embora com gratidão cada vez menos à medida que passamos de 2014 e além) é rentável para suportar navegadores antigos como o IE7 ...
joshuahedlund
2
@ njzk2 para lidar com uma cadeia vazia, você pode atualizar a isto: return s && s[0].toUpperCase() + s.slice(1);
joelvh
188

Se você estiver interessado no desempenho de alguns métodos diferentes publicados:

Aqui estão os métodos mais rápidos com base neste teste jsperf (ordenado do mais rápido para o mais lento).

Como você pode ver, os dois primeiros métodos são essencialmente comparáveis ​​em termos de desempenho, enquanto alterar o String.prototypeé de longe o mais lento em termos de desempenho.

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

insira a descrição da imagem aqui

Josh Crozier
fonte
1
Parece que o código de inicialização não faz a diferença seja: jsperf.com/capitalize-first-letter-of-string/2
user420667
6
Observe também que a substituição .slice(1)por .substr(1)melhoraria ainda mais o desempenho.
Przemek
2
Consideração razoável. No entanto, lembre-se de que, em muitos casos, o impacto no desempenho nem é perceptível: mesmo a abordagem "mais lenta" lidaria com seqüências de caracteres de 19k em 10 ms. Portanto, escolha o mais confortável de usar.
Citando Eddie
1
Caso alguém tenha curiosidade (como eu) de como o desempenho disso aumentou nos últimos quatro anos, as operações / segundo da terceira função em um macbook pro de 2018 são de 135.307.869, sendo essencialmente 12,4 vezes mais rápido.
Carlo Field
151

Para outro caso, preciso que ela coloque em maiúscula a primeira letra e minúscula o restante. Os seguintes casos me fizeram mudar esta função:

//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
fonte
1
"... mas não mude o caso de nenhuma das outras letras". Esta não é uma resposta correta para a pergunta feita pelo OP.
Carlos Muñoz
2
@ CarlosMuñoz se você ler a frase de abertura, ele diz que isso é para um caso diferente.
TMH
3
@ TomHart É exatamente por isso que não é uma solução para a pergunta. Deve ser um comentário ou outra pergunta e resposta
Carlos Muñoz
15
Eu concordo com você nisso, mas posso ver muitas pessoas terminando aqui procurando fazer o que essa resposta faz.
TMH
74

Esta é a solução 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
fonte
5
.slice()é mais lento do que .substring(), str[0]seria undefinedpara uma cadeia vazia e usando literais de modelo para juntar as duas introduz peças aqui 8 caracteres, enquanto que +iria introduzir única 3.
Przemek
4
O ponto da minha resposta Prz é mostrar os novos recursos suportados pelo ES6, especificamente modelos literais que não foram mencionados em outras postagens. A idéia do StackOverflow é fornecer ao pesquisador “opções”. Eles podem pegar o conceito de Literais de Modelo descrito nesta resposta e combiná-lo com aprimoramentos de micro-velocidade como Substring v. Slice se o aplicativo exigir esses milissegundos extras salvos. Minha resposta também não inclui nenhum teste de unidade, o que mostra que você nunca deve copiar uma resposta diretamente do StackOverflow. Presumo que o desenvolvedor pegue minha resposta e a adapte.
Sterling Bourne
Você não ganha nada usando literais de modelo aqui e o ${}just adiciona ruído. const newStr = str[0].toUpperCase() + str.slice(1);é mais fácil de ler.
Boris
1
Concorde em discordar sobre o que é mais fácil de ler.
Sterling Bourne
67

Se você já está (ou está pensando em usar) lodash, a solução é fácil:

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

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

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

Consulte os documentos: 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'

Baunilha js para a primeira letra maiúscula:

function upperCaseFirst(str){
    return str.charAt(0).toUpperCase() + str.substring(1);
}
chovy
fonte
11
Eu acho que a preferência deve ser os Js de baunilha, já que a maioria das pessoas não baixa um framework inteiro apenas para capitalizar uma string.
GGG
7
Em todos os meus projetos até agora, nunca usei lodash. Não se esqueça também de que a maioria das pessoas no google terminará nesta página, e listar uma estrutura como alternativa é bom, mas não como resposta principal.
GGG
2
Como outras respostas usam vanilla js, é bom ter uma resposta como essa, já que muitos de nós usam lodash / underscore.
Lu Roman
1
Essa não é a resposta correta, já que o OP solicita agora fazê-lo em Javascript, não em uma biblioteca Javascript, que importa uma biblioteca inteira como uma dependência do seu projeto. Não use.
Dudewad
1
A pergunta do OP está em baunilha no final da minha resposta.
chovy
62

Coloque em maiúscula a primeira letra de todas as palavras em uma sequência:

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
fonte
14
Releia a pergunta: desejo colocar em maiúscula o primeiro caractere de uma string, mas não alterar o caso de nenhuma das outras letras.
JimmyPena
2
Eu sei que sim. Eu acrescentaria uma coisa, caso a string inteira comece com letras maiúsculas: pieces [i] = j + pieces [i] .substr (1) .toLowerCase ();
Malovich 20/12/12
4
Outra solução para este caso: function capitaliseFirstLetters (s) {return s.split ("") .map (function (w) {return w.charAt (0) .toUpperCase () + w.substr (1)}). Join ("")} Pode ser uma linha única agradável, se não for colocada em uma função.
Luke Channings
Seria melhor primeiro minúsculas a seqüência inteira
Magico
Além dessa função que não responde à pergunta, ela também é complicada demais. s => s.split(' ').map(x => x[0].toUpperCase() + x.slice(1)).join(' ')
28717 OverCoder
48

Poderíamos conseguir o primeiro personagem com um dos meus favoritos RegExp, parece um smiley fofo:/^./

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

E para todos os viciados em café:

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

... e para todos os que pensam que há uma maneira melhor de fazer isso, sem estender os protótipos nativos:

var capitalize = function (input) {
  return input.replace(/^./, function (match) {
    return match.toUpperCase();
  });
};
yckart
fonte
2
Existe uma maneira melhor de fazer isso sem modificar o protótipo String.
Big McLargeHuge
2
@ davidkennedy85 Claro! Mas esta é a maneira simples, não a melhor maneira ... ;-)
yckart
Caro senhor, há um milhão de respostas para esta pergunta! Sua solução parece ainda melhor no es6. 'Answer'.replace(/^./, v => v.toLowerCase())
31519 stwilz
47

Usar:

var str = "ruby java";

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

Ele será exibido "Ruby java"no console.

AMIC MING
fonte
Solução de uma linha.
Ahmad Sharif
45

Se você usar underscore.js ou Lo-Dash , a biblioteca underscore.string fornecerá extensões de cadeia, incluindo maiúsculas:

_.capitalize (string) Converte a primeira letra da string em maiúsculas.

Exemplo:

_.capitalize("foo bar") == "Foo bar"
andersh
fonte
3
Desde a versão 3.0.0 , o Lo-Dash tem esse método de string disponível por padrão. Assim como descrito nesta resposta: _.capitalize("foo") === "Foo".
bardzusny
Também há a função underscore.js útil chamada humanize. Ele converte uma string sublinhada, camelizada ou dasherized em uma humanizada. Também remove os espaços em branco iniciais e finais e remove o postfix '_id'.
Stepan Zakharov
1
A partir da versão 4 *, o Lodash também minúscula () todas as outras letras, tenha cuidado!
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 depois:

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

Atualize Nov.2016 (ES6), apenas por diversão:

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

então capitalize("hello") // Hello

Abdennour TOUMI
fonte
3
Penso que esta é uma má solução por 2 razões: Modificar o protótipo de um primitivo é uma má ideia. Se as especificações mudarem e eles decidirem escolher 'capitalizar' como um novo nome de propriedade proto, você estará quebrando a funcionalidade do idioma principal. Além disso, o nome do método escolhido é ruim. À primeira vista, acho que isso vai capitalizar toda a cadeia. Usar um nome mais descritivo, como o ucFirst do PHP ou algo semelhante, pode ser uma idéia melhor.
Dudewad
A outra resposta ES6 é mais simples: const capitalize = ([first,...rest]) => first.toUpperCase() + rest.join('').toLowerCase();.
Dan Dascalescu 22/06/19
44

MAIS CURTO 3 soluções, 1 e 2 casos punho quando sstring é "", 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

Kamil Kiełczewski
fonte
42

Apenas CSS

p::first-letter {
  text-transform: uppercase;
}
  • Apesar de ser chamado ::first-letter, ele se aplica ao primeiro caractere , ou seja, no caso de string %a, esse seletor se aplicaria %e, como tal a, não seria maiúsculo.
  • No IE9 + ou IE5.5 +, ele é suportado em notação herdada com apenas dois pontos ( :first-letter).

ES2015 one-liner

Como existem inúmeras respostas, mas nenhuma no ES2015 que resolveria o problema original de forma eficiente, vim com o seguinte:

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

Observações

  • parameters => functioné a chamada função de seta .
  • Eu fui com o nome em capitalizeFirstCharvez de capitalizeFirstLetter, porque o OP não solicitou código que colocasse em maiúscula a primeira letra de toda a string, mas o primeiro caractere (se for letra, é claro).
  • const nos dá a capacidade de declarar capitalizeFirstChar como constante, o que é desejado, pois como programador você deve sempre declarar explicitamente suas intenções.
  • No benchmark que realizei, não houve diferença significativa entre string.charAt(0)e string[0]. Observe, no entanto, que string[0]seria undefinedpara uma string vazia, portanto, ela deve ser reescrita para string && string[0], que é muito detalhada, em comparação com a alternativa.
  • string.substring(1)é mais rápido que string.slice(1).

Referência

  • 4.956.962 ops / s ± 3,03% para esta solução,
  • 4.577.946 ops / s ± 1,2% para a resposta mais votada.
  • Criado com JSBench.me no Google Chrome 57.

Comparação de soluções

Przemek
fonte
@ Verde: sim , você tem certeza de que especificou o seletor com dois pontos?
Przemek
1
Na verdade, você não deseja usar o sinal de mais (+) como um método de concatenação no ES6. Você vai querer usar literais de modelo: eslint.org/docs/rules/prefer-template
Sterling Bourne
42

Existe uma maneira muito simples de implementá-lo por substituição . Para ECMAScript 6:

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

Resultado:

'Foo'
Little Roys
fonte
1
Melhor resposta de longe e pontos extras por mostrar a sintaxe regex lambda. Eu gosto especialmente deste, pois pode ser um recortar e colar fluente em qualquer lugar.
Wade Hatler
Usando /^[a-z]/iserá melhor do que usar .como o anterior não tentará substituir qualquer carácter diferente de alfabetos
Código Maniac
38

Parece ser mais fácil no CSS:

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

Isto é da propriedade de transformação de texto CSS (na W3Schools ).

Ryan
fonte
29
@ Simon Não é declarado que a string necessariamente será impressa como parte de um documento HTML - o CSS só será útil se for.
Adam Hepton 18/01/12
9
Adam, é verdade, mas eu acho que mais de 95% do Javascript lá fora é usado com HTML e CSS. Infelizmente, a instrução "capitalize" realmente coloca em maiúscula todas as palavras ; portanto, você ainda precisa que o JS coloque em maiúscula apenas a primeira letra da string.
Simon East
18
Incorreto, Dinesh. Ele disse que o primeiro caractere da corda .
Simon Médio
81
Esta resposta, apesar de ter um número ridículo de votos positivos, está errada, pois capitalizará a primeira letra de cada palavra. @Ryan, você ganhará um distintivo disciplinado se o excluir. Por favor, faça isso.
Dan Dascalescu 7/11
10
Concordo com @DanDascalescu - a resposta de Ryan está completamente errada.
Timo
38
var capitalized = yourstring[0].toUpperCase() + yourstring.substr(1);
zianwar
fonte
38

Não vi menção nas respostas existentes de questões relacionadas a pontos de código do plano astral ou à internacionalização. "Maiúsculas" não significa a mesma coisa em todos os idiomas usando um determinado script.

Inicialmente, não encontrei respostas abordando questões relacionadas aos pontos de código do plano astral. Há um , mas está um pouco enterrado (como este, eu acho!)


A maioria das funções propostas é assim:

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

No entanto, alguns caracteres em caixa ficam fora do BMP (plano multilíngue básico, pontos de código U + 0 a U + FFFF). Por exemplo, pegue este texto Deseret:

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

O primeiro caractere aqui falha ao capitalizar porque as propriedades de cadeias indexadas por matriz não acessam "caracteres" ou pontos de código *. Eles acessam unidades de código UTF-16. Isso também é verdade ao fatiar - os valores do índice apontam para as unidades de código.

Acontece que as unidades de código UTF-16 são 1: 1 com pontos de código USV em dois intervalos, U + 0 a U + D7FF e U + E000 a U + FFFF, inclusive. A maioria dos personagens incluídos se encaixa nesses dois intervalos, mas não em todos eles.

A partir do ES2015, lidar com isso ficou um pouco mais fácil. String.prototype[@@iterator]produz strings correspondentes aos pontos de código **. Então, por exemplo, podemos fazer isso:

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

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

Para seqüências mais longas, isso provavelmente não é muito eficiente *** - não precisamos iterar o restante. Poderíamos usar String.prototype.codePointAtpara chegar à primeira letra (possível), mas ainda precisaríamos determinar onde a fatia deveria começar. Uma maneira de evitar a repetição do restante seria testar se o primeiro ponto de código está fora do BMP; se não estiver, a fatia começará em 1 e, se estiver, a fatia começará em 2.

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

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

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

Você pode usar a matemática bit a bit em vez de > 0xFFFFlá, mas provavelmente é mais fácil entender dessa maneira e conseguiria a mesma coisa.

Também podemos fazer isso funcionar no ES5 e abaixo, levando essa lógica um pouco mais longe, se necessário. Não há métodos intrínsecos no ES5 para trabalhar com pontos de código, portanto, precisamos testar manualmente se a primeira unidade de código é uma substituta ****:

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

No início, também mencionei considerações sobre internacionalização. Algumas delas são muito difíceis de serem explicadas porque exigem conhecimento não apenas de qual idioma está sendo usado, mas também podem exigir conhecimento específico das palavras no idioma. Por exemplo, o dígrafo irlandês "mb" coloca em maiúscula como "mB" no início de uma palavra. Outro exemplo, o eszett alemão, nunca inicia uma palavra (afaik), mas ainda ajuda a ilustrar o problema. O eszett em minúsculas ("ß") coloca em maiúscula em "SS", mas "SS" pode em minúsculas em "ß" ou "ss" - é necessário conhecimento fora da banda do idioma alemão para saber qual é o correto!

O exemplo mais famoso desses tipos de questões, provavelmente, é o turco. No latim turco, a forma maiúscula de i é ©, enquanto a minúscula de I é i - são duas letras diferentes. Felizmente, temos uma maneira de explicar isso:

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

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

Em um navegador, a tag de idioma mais preferida do usuário é indicada por navigator.language, uma lista em ordem de preferência é encontrada em navigator.languagese um determinado idioma do elemento DOM pode ser obtido (geralmente) Object(element.closest('[lang]')).lang || YOUR_DEFAULT_HEREem documentos em vários idiomas.

Nos agentes que oferecem suporte às classes de caracteres de propriedade Unicode no RegExp, introduzidos no ES2018, podemos limpar ainda mais as coisas expressando diretamente em quais caracteres estamos interessados:

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

Isso pode ser ajustado um pouco para também manipular letras maiúsculas em várias palavras com uma precisão bastante boa. A propriedade de caractere CWUou Changes_When_Uppercased corresponde a todos os pontos de código que, assim, mudam quando estão em maiúsculas. Podemos tentar isso com caracteres digigráficos com letras maiúsculas como o holandês ij, por exemplo:

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

No momento da redação deste artigo (fevereiro de 2020), o Firefox / Spidermonkey ainda não havia implementado nenhum dos recursos RegExp introduzidos nos últimos dois anos *****. Você pode verificar o status atual desse recurso na tabela de compatibilidade Kangax . Babel é capaz de compilar literais RegExp com referências de propriedades a padrões equivalentes sem eles, mas esteja ciente de que o código resultante pode ser enorme.


Com toda a probabilidade, as pessoas que fazem essa pergunta não se preocuparão com a capitalização ou internacionalização da Deseret. Mas é bom estar ciente desses problemas, porque há uma boa chance de que você os encontre eventualmente, mesmo que não sejam preocupações no momento. Eles não são casos extremos, ou melhor, não são casos extremos por definição - existe um país inteiro onde a maioria das pessoas fala turco, de qualquer maneira, e a confluência de unidades de código com pontos de código é uma fonte bastante comum de bugs (especialmente com em relação a emoji). Ambas as strings e a linguagem são bastante complicadas!


* As unidades de código do UTF-16 / UCS2 também são pontos de código Unicode no sentido de que, por exemplo, o U + D800 é tecnicamente um ponto de código, mas não é isso que "significa" aqui ... mais ou menos ... embora fique bonito difusa. O que os substitutos definitivamente não são, no entanto, são os USVs (valores escalares Unicode).

** Embora se uma unidade de código substituto for "órfã" - isto é, não faz parte de um par lógico - você ainda poderá obter substitutos aqui também.

*** talvez. Eu não testei. A menos que você tenha determinado que a capitalização é um gargalo significativo, eu provavelmente não a suoria - escolha o que você achar mais claro e legível.

**** Essa função pode desejar testar a primeira e a segunda unidades de código em vez de apenas a primeira, pois é possível que a primeira unidade seja uma substituta órfã. Por exemplo, a entrada "\ uD800x" colocaria em maiúscula o X como está, o que pode ou não ser esperado.

***** Aqui está a questão do Bugzilla, se você quiser acompanhar o progresso mais diretamente.

Ponto e vírgula
fonte
2
Esta resposta precisa ser movida para a frente.
Rúnar Berg
Obrigado @ RúnarBerg - desde que seu comentário me lembrou disso, li novamente e percebi que havia deixado de fora um caso final e uma solução que vale a pena mencionar. Também tentou esclarecer algumas das terminologias melhor.
Ponto
Ótima resposta .....
Ben Aston
Esta resposta é excelente, eu gostaria de poder votar mais.
David Barker
37

É sempre melhor lidar com esses tipos de coisas usando CSS primeiro , em geral, se você pode resolver algo usando CSS, faça isso primeiro e tente o JavaScript para resolver seus problemas. Portanto, nesse caso, tente usar :first-letterCSS e apliquetext-transform:capitalize;

Portanto, tente criar uma classe para isso, para que você possa usá-la globalmente, por exemplo: .first-letter-uppercasee adicione algo como abaixo no seu CSS:

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

Além disso, a opção alternativa é JavaScript, então o melhor será algo como isto:

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

e chame assim:

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 você deseja reutilizá-lo repetidamente, é melhor anexá-lo à String nativa do javascript, então algo como abaixo:

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

e chame como abaixo:

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

Se você deseja reformatar o texto com letras maiúsculas, modifique os outros exemplos como:

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

Isso garantirá que o seguinte texto seja alterado:

TEST => Test
This Is A TeST => This is a test
monokrome
fonte
Provavelmente importante notar que este também irá converter coisas como siglas para minúsculas, então talvez não a melhor idéia na maioria dos casos
monokrome
Além disso, o GAMITG realmente fez uma edição apenas para remover um espaço em branco de uma parte sem código da postagem? O_O
monokrome 28/08
btw, isso quebrará siglas maiúsculas, então tenha cuidado pessoal <3
monokrome 15/03/19
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.
fonte
Feito @Ram. Também incluíram exemplos.
Fredrik A.
Como isso é melhor do que a resposta de 2009 ?
Dan Dascalescu 27/01/19
1
Não é @DanDascalescu. Suponho que você possa argumentar que substr/ substringé um pouco mais semântico em oposição a slice, mas isso é apenas uma questão de preferência. No entanto, incluí exemplos com as strings fornecidas na pergunta, que é um toque agradável que não está presente no exemplo '09. Sinceramente, acho que tudo se resume a 15 anos de idade me querendo karma em StackOverflow;)
Fredrik A.
34

Aqui está uma função chamada ucfirst () (abreviação de "primeira letra maiúscula"):

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

Você pode colocar em maiúscula uma string chamando ucfirst ("some string") - por exemplo,

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

Ele funciona dividindo a corda em duas partes. Na primeira linha, ele extrai firstLetter e, na segunda linha, coloca em maiúscula firstLetter chamando firstLetter.toUpperCase () e o une ao restante da string, que é encontrada chamando str.substr (1) .

Você pode pensar que isso falharia em uma string vazia e, de fato, em um idioma como C, você teria que atender a isso. No entanto, no JavaScript, quando você pega uma substring de uma string vazia, você apenas recebe uma string vazia de volta.

Robert Wills
fonte
4
Use String.substring () ou String.slice () ... Não use substr () - está obsoleto.
James
7
@ 999: onde diz que substr()está obsoleto? Ainda não é , três anos depois, e muito menos em 2009, quando você fez esse comentário.
Dan Dascalescu
substr()pode não ser marcado como reprovado por qualquer implementação popular do ECMAScript (duvido que não desapareça tão cedo), mas não faz parte das especificações do ECMAScript. A 3ª edição das especificações menciona isso no anexo não normativo para "sugerir semântica uniforme para essas propriedades sem tornar as propriedades ou suas semânticas parte deste padrão".
Peter Rust
2
Ter 3 métodos que fazem a mesma coisa ( substring, substre slice) é demais, IMO. Eu sempre uso sliceporque ele suporta índices negativos, não possui o comportamento confuso de troca de argumentos e sua API é semelhante a sliceoutras linguagens.
22812 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();

Esta é uma sequência de texto => Esta é uma sequência de texto

Murat Kucukosman
fonte
20
Expressões regulares são um exagero para isso.
Anthony Sottile
+1, é isso que eu realmente estava procurando. Há um menor erro, porém, ele deve ser return.this.toLocaleLowerCase().replace(...
tomdemuyt
+1, encontrei esta página procurando uma versão javascript do phps ucfirst, que suspeito ser a forma como a maioria das pessoas a encontra.
Benubird
@DanDascalescu Achei isso útil, então +1 utilitarismo e -1 retentividade anal. Ele incluiu um exemplo, portanto, sua função é clara.
Travis Webb
String.prototype.capitalize = function(){ return this.replace( /(^|\s)[a-z]/g , function(m){ return m.toUpperCase(); }); }; Refatoro um pouco seu código, você precisa apenas de uma primeira correspondência.
precisa saber é o seguinte
28
var str = "test string";
str = str.substring(0,1).toUpperCase() + str.substring(1);
MaxEcho
fonte
21

Faça o checkout desta solução:

var stringVal = 'master';
stringVal.replace(/^./, stringVal[0].toUpperCase()); // returns Master 
Raju Bera
fonte
3
Essa deve ser a resposta aceita. A solução principal não deve usar uma estrutura como sublinhado.
Adam McArthur
3
Salve algumas teclas;)stringVal.replace(/^./, stringVal[0].toUpperCase());
Alfredo Delgado
1
O Regex não deve ser usado onde não for necessário. É muito ineficiente e também não torna o código mais conciso. Além disso, stringVal[0]seria undefinedvazio stringVal, e, como tal, a tentativa de acessar a propriedade .toUpperCase()geraria um erro.
Przemek 23/09
20
yourString.replace(/^[a-z]/, function(m){ return m.toUpperCase() });

(Você pode encapsulá-lo em uma função ou até mesmo adicioná-lo ao protótipo String, se você o usar com frequência.)

Simon
fonte
5
Embora isso tenha alguns votos, essa é de longe a solução mais lenta publicada aqui. Eu coloquei um pouco speedtest com a maioria das respostas populares a partir deste post, aqui: forwebonly.com/...
Robin van Baalen
@RobinvanBaalen Seu link agora está quebrado. Tem um atualizado?
Brad
1
Regexp é um exagero para isso, prefere o mais simples: str.charAt (0) .toUpperCase () + str.slice (1)
Simon
@ Brad infelizmente não #
Robin van Baalen
Muitas vezes, se você deseja resolver seu problema com regex, acaba com dois problemas.
Przemek 23/09
19

A ucfirstfunção funciona se você fizer assim.

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

Obrigado JP pela aclaração.

raphie
fonte
2
belo nome para a função! Seu nome é idêntico ao equivalente ao PHP. Na verdade, existe uma biblioteca inteira de funções PHP escritas em JS; chama-se PHP.js e pode ser encontrado em http://phpjs.org
Hussam
11
Um liner:string[0].toUpperCase() + string.substring(1)
dr.dimitru 25/11
@TarranJones aqui é um liner à prova de balas:(string[0] || '').toUpperCase() + string.substring(1)
dr.dimitru
@ dr.dimitru: Em vez de idiomático, (string[0] || '')você poderia apenas string.charAt(0).
Przemek
18

Você pode fazer isso em uma linha como esta

string[0].toUpperCase() + string.substring(1)
Qwerty
fonte
Essa resposta já foi dada em 2009 .
Dan Dascalescu 27/01/19
17
yourString.replace(/\w/, c => c.toUpperCase())

Eu achei essa função de seta mais fácil. Substituir corresponde ao primeiro caractere da letra ( \w) da sua sequência e o converte em maiúsculas. Nada extravagante necessário.

Lobo
fonte
1
Essa deve ser a resposta aceita, mas é quase a última, pois o SO continua premiando perguntas desatualizadas. Btw, é melhor usar /./para dois motivos: /\w/irá ignorar todos os não anterior carta caracteres (assim @@ abc vai se tornar @@ Abc), e então ele não funciona com caracteres não-latinos
Cristian Traina