¿Cómo hago la primera letra de una cadena en mayúscula en JavaScript?

3764

¿Cómo hago la primera letra de una cadena en mayúscula, pero no cambio el caso de ninguna de las otras letras?

Por ejemplo:

  • "this is a test" -> "This is a test"
  • "the Eiffel Tower" -> "The Eiffel Tower"
  • "/index.html" -> "/index.html"
Robert Wills
fuente
12
Underscore tiene un plugin llamado underscore.string que incluye esto y muchas otras herramientas excelentes.
Aaron
¿Qué pasa con:return str.replace(/(\b\w)/gi,function(m){return m.toUpperCase();});
Muhammad Umer
111
Más simple:string[0].toUpperCase() + string.substring(1)
dr.dimitru
77
`${s[0].toUpperCase()}${s.slice(1)}`
noego
([initial, ...rest]) => [initial.toUpperCase(), ...rest].join("")
Константин Ван

Respuestas:

5811

La solución básica es:

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

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

Algunas otras respuestas se modifican String.prototype(esta respuesta también solía hacerlo), pero aconsejaría en contra de esto ahora debido a la capacidad de mantenimiento (difícil de averiguar dónde se agrega la función prototypey podría causar conflictos si otro código usa el mismo nombre / un navegador agrega una función nativa con ese mismo nombre en el futuro).

... y luego, hay mucho más en esta pregunta cuando se considera la internacionalización, como lo muestra esta asombrosamente buena respuesta (enterrada a continuación).

Si desea trabajar con puntos de código Unicode en lugar de unidades de código (por ejemplo, para manejar caracteres Unicode fuera del plano multilingüe básico), puede aprovechar el hecho de que String#[@iterator]funciona con puntos de código, y puede usarlo toLocaleUpperCasepara obtener mayúsculas de localización correcta:

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 obtener aún más opciones de internacionalización, consulte la respuesta original a continuación .

Steve Harrison
fuente
99
subcadena se entiende en más navegadores que substr
mplungjan
66
agregar a karim79: probablemente sea excesivo convertirlo en una función, ya que JavaScript hará lo mismo con la variable sin el ajuste de la función. Supongo que sería más claro usar una función, pero de lo contrario es nativo, ¿por qué complicarlo con un contenedor de funciones?
Ross
18
¿No deberíamos también bajar el segmento (1)?
hasen
177
No, porque el PO dio este ejemplo: the Eiffel Tower -> The Eiffel Tower. Además, la función se llama capitaliseFirstLetterno capitaliseFirstLetterAndLowerCaseAllTheOthers.
prohibición de geoingeniería el
22
¿A nadie le importa la regla importante de la POO? - ¿ Nunca editas objetos que no te pertenecen? . Por cierto, este one-liner se ve mucho más elegante:string[0].toUpperCase() + string.substring(1)
dr.dimitru
1350

Aquí hay un enfoque más orientado a objetos:

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

Llamaría a la función, así:

"hello world".capitalize();

Con la salida esperada siendo:

"Hello world" 
Steve Hansell
fuente
24
Me gusta esta solución porque es como Ruby, ¡y Ruby es dulce! :) return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
Pongo en
164
En este mundo post-Prototype.js, no se sugiere cambiar o extender los objetos nativos.
Ryan
191
@rxgx - El hombre del saco "no se extienda" ahora está comenzando a morir (gracias a Dios), y la gente está sacando la cabeza del jSand y se da cuenta de que es solo una característica del lenguaje. Solo porque Prototype.js extendió el Objeto por un breve tiempo, no significa que extender Natives sea malo. No debe hacerlo si está escribiendo código para un consumidor desconocido (como un script de análisis que va en sitios aleatorios), pero aparte de eso está bien.
csuwldcat
44
@csuwldcat ¿Qué sucede si otra biblioteca que está utilizando agrega su propia mayúscula sin que usted lo sepa? Extender prototipos es una mala forma, independientemente de si Prototype.js lo hizo o no. Con ES6, los intrínsecos le permitirán tener su pastel y comérselo también. Creo que podría confundir al "hombre del saco" que muere por las personas que crean calzas que cumplen con la especificación ECMASCRIPT. Estas cuñas están perfectamente bien porque otra biblioteca que agregó una cuña lo implementaría de la misma manera. Sin embargo, debe evitarse agregar sus propios elementos intrínsecos no especificados.
Justin Meyer
44
Extender a los nativos es EXTREMADAMENTE una mala práctica. Incluso si dice "oh, nunca voy a usar este código con otra cosa", usted (u otra persona) probablemente lo hará. Luego pasarán tres días tratando de descubrir algún error matemático extraño porque alguien extendió Number.money () para tratar con la moneda un poco diferente a la de su otra biblioteca. En serio, he visto que esto suceda en una gran empresa y no vale la pena depurar a nadie para descubrir un desarrollador de la biblioteca enredado con los prototipos nativos.
phreakhead
574

En CSS:

p:first-letter {
    text-transform:capitalize;
}
sam6ber
fuente
80
OP está pidiendo una solución JS.
Antonio Max
129129
$ ('# mystring_id'). text (string) .css ('text-transform', 'capitalize');
DonMB
21
Además, esto solo afecta la visualización de la cadena, no el valor real. Si está en un formulario, por ejemplo, el valor aún se enviará tal cual.
dmansfield
12
Esta respuesta me ayudó a darme cuenta de que una solución CSS realmente era más apropiada para lo que estaba haciendo. @dudewad: La respuesta probablemente debería dar un descargo de responsabilidad de que esta no es una solución JS, pero podría ser más apropiada según la necesidad.
joshden
58
Para aproximadamente el 80% de los espectadores que llegan a esta pregunta, esta será la mejor respuesta. No es una respuesta a la pregunta , sino al problema .
Jivan
290

Aquí hay una versión abreviada de la respuesta popular que obtiene la primera letra tratando la cadena como una matriz:

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

Actualizar:

De acuerdo con los comentarios a continuación, esto no funciona en IE 7 o inferior.

Actualización 2:

Para evitar undefinedcadenas vacías (consulte el comentario de @ njzk2 a continuación ), puede verificar si hay una cadena vacía:

function capitalize(s)
{
    return s && s[0].toUpperCase() + s.slice(1);
}
joelvh
fuente
23
Esto no funcionará en IE <8, ya que esos navegadores no admiten la indexación de cadenas. IE8 lo admite, pero solo para literales de cadena, no para objetos de cadena.
Mathias Bynens
52
a quién le importa, el mercado IE7 es menos del 5%! y esas son probablemente la vieja máquina de tu gremma y grempa. Digo código corto FTW!
vsync
@MathiasBynens ¿Sabe si esto afecta a los navegadores antiguos que no son IE o solo IE7? Si no hay otros navegadores afectados por la indexación de literales de cadena en 2014, deberíamos estar bien. :)
hexalys
3
@vsync Solo quería decir que dependiendo de la demografía de su usuario, a veces (aunque cada vez menos a medida que pasamos 2014 y más allá) es rentable admitir navegadores antiguos como IE7 ...
joshuahedlund
2
@ njzk2 para manejar una cadena vacía, puede actualizar a esto: return s && s[0].toUpperCase() + s.slice(1);
joelvh
188

Si está interesado en el rendimiento de algunos métodos diferentes publicados:

Estos son los métodos más rápidos basados ​​en esta prueba jsperf (ordenados de más rápido a más lento).

Como puede ver, los dos primeros métodos son esencialmente comparables en términos de rendimiento, mientras que la alteración String.prototypees, con mucho, la más lenta en términos de rendimiento.

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

ingrese la descripción de la imagen aquí

Josh Crozier
fuente
1
Parece que el código de inicialización tampoco hace la diferencia: jsperf.com/capitalize-first-letter-of-string/2
user420667
66
Tenga en cuenta también que reemplazar .slice(1)con .substr(1)mejoraría aún más el rendimiento.
Przemek
2
Consideración razonable Sin embargo, tenga en cuenta que en muchos casos el impacto en el rendimiento ni siquiera es notable: incluso el enfoque "más lento" manejaría cadenas de 19k en 10 ms. Así que tome el más cómodo de usar para usted.
Citando a Eddie el
1
En caso de que alguien tenga curiosidad (como yo) de cómo ha aumentado el rendimiento de esto en los últimos cuatro años, las operaciones / segundo de la tercera función en un macbook pro 2018 es de 135.307.869, por lo que es esencialmente 12.4 veces más rápido.
Carlo Field
151

Para otro caso, lo necesito para poner en mayúscula la primera letra y poner en minúscula el resto. Los siguientes casos me hicieron cambiar esta función:

//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
fuente
1
"... pero no cambia el caso de ninguna de las otras letras". Esta no es una respuesta correcta a la pregunta que hizo el OP.
Carlos Muñoz
2
@ CarlosMuñoz si lees la oración inicial, dice que esto es para un caso diferente.
TMH
3
@TomHart Eso es exactamente por qué no es una solución para la pregunta. Debe ser un comentario u otra pregunta y respuesta
Carlos Muñoz
15
Estoy de acuerdo con usted en eso, pero puedo ver a muchas personas terminando aquí buscando hacer lo que hace esta respuesta.
TMH
74

Esta es la solución 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
fuente
55
.slice()es más lento que .substring(), str[0]sería undefinedpara una cadena vacía y usar literales de plantilla para unir las dos partes introduce aquí 8 caracteres, mientras +que solo introduciría 3.
Przemek
44
El punto de mi respuesta Prz es mostrar las nuevas características compatibles con ES6, específicamente los literales de plantilla que no se mencionaron en otras publicaciones. La idea de StackOverflow es dar al buscador "opciones". Pueden tomar el concepto de Literales de plantilla descrito en esta respuesta y combinarlo con mejoras de microvelocidad como Substring v. Slice si su aplicación requiere esos milisegundos adicionales guardados. Mi respuesta tampoco incluye ninguna Prueba de unidad, lo que demuestra que nunca debes copiar una respuesta de StackOverflow directamente. Supongo que el desarrollador tomará mi respuesta y la adaptará.
Sterling Bourne
No gana nada al usar literales de plantilla aquí y el ${}solo agrega ruido. const newStr = str[0].toUpperCase() + str.slice(1);Es más fácil de leer.
Boris
1
Acuerde estar en desacuerdo sobre lo que es más fácil de leer.
Sterling Bourne
67

Si ya está (o está considerando) usar lodash, la solución es fácil:

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

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

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

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

Vanilla js para la primera mayúscula:

function upperCaseFirst(str){
    return str.charAt(0).toUpperCase() + str.substring(1);
}
chovy
fuente
11
Creo que la preferencia debería ser J vainilla ya que la mayoría de las personas no descargarán un marco completo solo para capitalizar una cadena.
GGG
77
En todos mis proyectos hasta ahora nunca he usado lodash. No olvide tampoco que la mayoría de las personas en Google terminarán en esta página, y enumerar un marco como alternativa está bien, pero no como una respuesta principal.
GGG
2
Como otras respuestas usan vanilla js, es bueno tener una respuesta como esta, ya que muchos de nosotros usamos lodash / subrayado.
Lu Roman
1
Esta no es la respuesta correcta, ya que el OP pide ahora que lo haga en Javascript, no en una biblioteca de Javascript, que importa una biblioteca completa como una dependencia de su proyecto. No lo uses
dudewad
1
La pregunta del OP está en vainilla al final de mi respuesta.
chovy
62

Poner en mayúscula la primera letra de todas las palabras en una cadena:

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
fuente
14
Vuelva a leer la pregunta: quiero poner en mayúscula el primer carácter de una cadena, pero no cambiar el caso de ninguna de las otras letras.
JimmyPena
2
Sé que lo hice. Agregaría una cosa, en caso de que toda la cadena comience con mayúsculas: pieces [i] = j + pieces [i] .substr (1) .toLowerCase ();
Malovich
44
Otra solución para este caso: function capitaliseFirstLetters (s) {return s.split ("") .map (function (w) {return w.charAt (0) .toUpperCase () + w.substr (1)}). Join ("")} Puede ser una buena frase si no se pone en una función.
Luke Channings
Sería mejor poner primero toda la cadena en minúscula
Magico
Aparte de esta función que no responde la pregunta, en realidad también es demasiado complicada. s => s.split(' ').map(x => x[0].toUpperCase() + x.slice(1)).join(' ')
OverCoder
48

Podríamos obtener el primer personaje con uno de mis favoritos RegExp, parece un lindo smiley:/^./

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

Y para todos los adictos al café:

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

... y para todos los que piensan que hay una mejor manera de hacerlo, sin extender los prototipos nativos:

var capitalize = function (input) {
  return input.replace(/^./, function (match) {
    return match.toUpperCase();
  });
};
yckart
fuente
2
Hay una mejor manera de hacerlo sin modificar el prototipo de String.
Big McLargeHuge
2
@ davidkennedy85 ¡Seguro! Pero esta es la forma más sencilla, no es el mejor camino ... ;-)
yckart
¡Querido señor, hay un millón de respuestas a esta pregunta! Su solución se ve aún mejor en es6. 'Answer'.replace(/^./, v => v.toLowerCase())
stwilz
47

Utilizar:

var str = "ruby java";

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

Saldrá "Ruby java"a la consola.

AMIC MING
fuente
Solución de una línea.
Ahmad Sharif
45

Si usa underscore.js o Lo-Dash , la biblioteca underscore.string proporciona extensiones de cadena, que incluyen mayúsculas:

_.capitalize (string) Convierte la primera letra de la cadena en mayúsculas.

Ejemplo:

_.capitalize("foo bar") == "Foo bar"
Andersh
fuente
3
Desde la versión 3.0.0 , Lo-Dash tiene este método de cadena disponible de forma predeterminada. Al igual que se describe en esta respuesta: _.capitalize("foo") === "Foo".
bardzusny
También hay funciones útiles de underscore.js llamadas humanize. Convierte una cuerda subrayada, camelizada o con guiones en una humanizada. También elimina los espacios en blanco iniciales y finales, y elimina el postfix '_id'.
Stepan Zakharov,
1
Desde la versión 4 *, Lodash también en minúscula () cada dos letras, ¡tenga 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
}

Y entonces:

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

Actualización de noviembre de 2016 (ES6), solo por diversión:

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

entonces capitalize("hello") // Hello

Abdennour TOUMI
fuente
3
Creo que esta es una solución pobre por 2 razones: modificar el prototipo de un primitivo es una mala idea. Si la especificación cambia y deciden elegir 'capitalizar' como un nuevo nombre de propiedad de proto, está rompiendo la funcionalidad del lenguaje principal. Además, el nombre del método elegido es pobre. A primera vista, creo que esto capitalizará toda la cadena. El uso de un nombre más descriptivo como ucFirst de PHP o algo similar podría ser una mejor idea.
dudewad
La otra respuesta es más simple ES6: const capitalize = ([first,...rest]) => first.toUpperCase() + rest.join('').toLowerCase();.
Dan Dascalescu
44

SHORTEST 3 soluciones, 1 y 2 manejan casos cuando la scadena es "", nully 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
fuente
42

Solo CSS

p::first-letter {
  text-transform: uppercase;
}
  • A pesar de ser llamado ::first-letter, se aplica al primer carácter , es decir, en el caso de una cadena %a, este selector se aplicaría %y, como tal a, no se capitalizaría.
  • En IE9 + o IE5.5 + se admite en notación heredada con solo dos puntos ( :first-letter).

ES2015 de una sola línea

Como hay numerosas respuestas, pero ninguna en ES2015 que resolvería el problema original de manera eficiente, se me ocurrió lo siguiente:

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

Observaciones

  • parameters => functionse llama función de flecha .
  • Fui con el nombre en capitalizeFirstCharlugar de capitalizeFirstLetter, porque OP no pidió un código que ponga en mayúscula la primera letra de toda la cadena, sino el primer carácter (si es letra, por supuesto).
  • constnos da la capacidad de declarar capitalizeFirstCharcomo constante, lo cual es deseable ya que como programador siempre debe indicar explícitamente sus intenciones.
  • En el punto de referencia que realicé no hubo diferencias significativas entre string.charAt(0)y string[0]. Sin embargo, string[0]tenga en cuenta que eso sería undefinedpara una cadena vacía, por lo que debe reescribirse string && string[0], lo que es demasiado detallado, en comparación con la alternativa.
  • string.substring(1)es más rápido que string.slice(1).

Punto de referencia

  • 4,956,962 ops / s ± 3.03% para esta solución,
  • 4,577,946 ops / s ± 1.2% para la respuesta más votada.
  • Creado con JSBench.me en Google Chrome 57.

Comparación de soluciones

Przemek
fuente
@Green: , ¿estás seguro de que has especificado un selector con dos puntos?
Przemek
1
En realidad, no desea utilizar el signo más (+) como método de concatenación en ES6. Querrá
Sterling Bourne
42

Hay una manera muy simple de implementarlo mediante el reemplazo . Para ECMAScript 6:

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

Resultado:

'Foo'
Little Roys
fuente
1
La mejor respuesta con diferencia, y puntos extra por mostrar la sintaxis de la expresión regular lambda. Me gusta especialmente este, ya que puede cortar y pegar con fluidez en cualquier lugar.
Wade Hatler
Usar /^[a-z]/iserá mejor que usar .ya que el anterior no intentará reemplazar ningún carácter que no sean alfabetos
Code Maniac
39

No vi ninguna mención en las respuestas existentes de cuestiones relacionadas con los puntos de código del plano astral o la internacionalización. "Mayúsculas" no significa lo mismo en todos los idiomas que utilizan un script determinado.

Inicialmente no vi ninguna respuesta que abordara los problemas relacionados con los puntos de código del plano astral. Hay uno , pero está un poco enterrado (¡como este, supongo!)


La mayoría de las funciones propuestas se ven así:

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

Sin embargo, algunos caracteres en mayúscula quedan fuera del BMP (plano multilingüe básico, puntos de código U + 0 a U + FFFF). Por ejemplo, tome este texto de Deseret:

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

El primer carácter aquí no puede capitalizarse porque las propiedades indexadas de la matriz de cadenas no acceden a "caracteres" o puntos de código *. Acceden a las unidades de código UTF-16. Esto también es cierto cuando se divide: los valores de índice apuntan a unidades de código.

Resulta que las unidades de código UTF-16 son 1: 1 con puntos de código USV dentro de dos rangos, U + 0 a U + D7FF y U + E000 a U + FFFF inclusive. La mayoría de los personajes en mayúsculas caen en esos dos rangos, pero no todos.

A partir de ES2015, lidiar con esto se volvió un poco más fácil. String.prototype[@@iterator]produce cadenas correspondientes a puntos de código **. Entonces, por ejemplo, podemos hacer esto:

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

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

Para cadenas más largas, esto probablemente no sea terriblemente eficiente ***: realmente no necesitamos repetir el resto. Podríamos usar String.prototype.codePointAtpara llegar a esa primera (posible) letra, pero aún tendríamos que determinar dónde debería comenzar el corte. Una forma de evitar iterar el resto sería probar si el primer punto de código está fuera del BMP; si no es así, el corte comienza en 1, y si lo es, el corte comienza en 2.

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

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

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

Podrías usar matemática bit a bit en lugar de > 0xFFFFallí, pero probablemente sea más fácil de entender de esta manera y lograrías lo mismo.

También podemos hacer que esto funcione en ES5 y versiones posteriores llevando esa lógica un poco más lejos si es necesario. No hay métodos intrínsecos en ES5 para trabajar con puntos de código, por lo que debemos probar manualmente si la primera unidad de código es un sustituto ****:

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

Al principio también mencioné consideraciones de internacionalización. Algunos de estos son muy difíciles de explicar porque requieren conocimiento no solo de qué idioma se está utilizando, sino que también pueden requerir un conocimiento específico de las palabras en el idioma. Por ejemplo, el dígrafo irlandés "mb" se capitaliza como "mB" al comienzo de una palabra. Otro ejemplo, el eszett alemán, nunca comienza una palabra (afaik), pero todavía ayuda a ilustrar el problema. La letra minúscula eszett ("ß") se escribe en mayúscula a "SS", pero "SS" podría minúscula a "ß" o "ss". ¡Se requiere conocimiento fuera de banda del idioma alemán para saber cuál es la correcta!

El ejemplo más famoso de este tipo de problemas, probablemente, es el turco. En latín turco, la forma mayúscula de i es İ, mientras que la forma minúscula de I es ı: son dos letras diferentes. Afortunadamente tenemos una forma de dar cuenta de esto:

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

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

En un navegador, la etiqueta de idioma más preferida del usuario se indica mediante navigator.language, se encuentra una lista en orden de preferencia navigator.languages, y se puede obtener el idioma de un elemento DOM dado (generalmente) con Object(element.closest('[lang]')).lang || YOUR_DEFAULT_HEREdocumentos en varios idiomas .

En los agentes que admiten clases de caracteres de propiedad Unicode en RegExp, que se introdujeron en ES2018, podemos limpiar más aún expresando directamente en qué caracteres estamos interesados:

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

Esto podría modificarse un poco para manejar también mayúsculas múltiples palabras en una cadena con bastante buena precisión. La propiedad de carácter CWUo Changes_When_Uppercased coincide con todos los puntos de código que, bueno, cambian cuando se escribe en mayúscula. Podemos probar esto con caracteres de dígrafo enchapados en títulos como el holandés ij por ejemplo:

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

En el momento de escribir este artículo (febrero de 2020), Firefox / Spidermonkey aún no ha implementado ninguna de las características RegExp introducidas en los últimos dos años *****. Puede verificar el estado actual de esta función en la tabla de compatibilidad de Kangax . Babel puede compilar literales RegExp con referencias de propiedad a patrones equivalentes sin ellos, pero tenga en cuenta que el código resultante puede ser enorme.


Con toda probabilidad, las personas que hagan esta pregunta no se preocuparán por la capitalización o la internacionalización de Deseret. Pero es bueno estar al tanto de estos problemas porque hay una buena posibilidad de que los encuentres eventualmente, incluso si no son preocupaciones actualmente. No son casos "límite", o mejor dicho, no son casos límite por definición : hay un país entero donde la mayoría de la gente habla turco, de todos modos, y la combinación de unidades de código con puntos de código es una fuente bastante común de errores (especialmente con respecto a los emoji). ¡Tanto las cadenas como el lenguaje son bastante complicados!


* Las unidades de código de UTF-16 / UCS2 también son puntos de código Unicode en el sentido de que, por ejemplo, U + D800 es técnicamente un punto de código, pero eso no es lo que "significa" aquí ... más o menos ... aunque se pone bastante borroso. Sin embargo, lo que los sustitutos definitivamente no son son los USV (valores escalares Unicode).

** Sin embargo, si una unidad de código sustituto está "huérfana", es decir, no forma parte de un par lógico, también podría obtener sustitutos aquí.

*** tal vez. No lo he probado. A menos que haya determinado que la capitalización es un cuello de botella significativo, probablemente no me preocupe, elija lo que considere más claro y legible.

**** tal función podría desear probar las unidades de código primera y segunda en lugar de solo la primera, ya que es posible que la primera unidad sea un sustituto huérfano. Por ejemplo, la entrada "\ uD800x" capitalizaría la X tal cual, lo que puede esperarse o no.

***** Aquí está el problema de Bugzilla si quieres seguir el progreso más directamente.

Punto y coma
fuente
2
Esta respuesta necesita ser movida al frente.
Rúnar Berg
Gracias @ RúnarBerg: como su comentario me recordó esto, lo leí nuevamente y me di cuenta de que había dejado de lado un caso final y una solución que vale la pena mencionar. También trató de aclarar algo de la terminología mejor.
Punto
Gran respuesta .....
Ben Aston
Esta respuesta es excelente, desearía poder votarla más.
David Barker
38

Parece ser más fácil en CSS:

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

Esto es de CSS Text -transform Property (en W3Schools ).

Ryan
fuente
29
@Simon No se dice que la cadena necesariamente se generará como parte de un documento HTML; CSS solo será útil si lo es.
Adam Hepton el
99
Adam, es cierto, pero supongo que más del 95% del Javascript se usa con HTML y CSS. Desafortunadamente, la declaración "capitalizar" en realidad capitaliza cada palabra , por lo que aún necesitaría JS para capitalizar solo la primera letra de la cadena.
Simon East
18
Incorrecto, Dinesh. Dijo el primer personaje de la cuerda .
Simon East
81
Esta respuesta, a pesar de tener un número ridículo de votos a favor, es incorrecta, ya que capitalizará la primera letra de cada palabra. @ Ryan, ganarás una insignia disciplinada si la eliminas . Por favor, hazlo.
Dan Dascalescu el
10
De acuerdo con @DanDascalescu: la respuesta de Ryan es completamente incorrecta.
Timo
38
var capitalized = yourstring[0].toUpperCase() + yourstring.substr(1);
zianwar
fuente
37

Siempre es mejor manejar este tipo de cosas usando CSS primero , en general, si puedes resolver algo usando CSS, ve por eso primero, luego prueba JavaScript para resolver tus problemas, así que en este caso intenta usar :first-letterCSS y aplicatext-transform:capitalize;

Intente crear una clase para eso, de modo que pueda usarla globalmente, por ejemplo: .first-letter-uppercasey agregue algo como a continuación en su CSS:

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

También la opción alternativa es JavaScript, así que lo mejor será algo como esto:

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

y lo llaman así:

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 desea reutilizarlo una y otra vez, es mejor adjuntarlo a la cadena nativa de JavaScript, por lo que algo como a continuación:

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

y llámalo como a continuación:

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

Si desea volver a formatear el texto en mayúsculas, puede modificar los otros ejemplos como tales:

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

Esto asegurará que se cambie el siguiente texto:

TEST => Test
This Is A TeST => This is a test
monokrome
fuente
Probablemente valga la pena señalar que esto también convertirá cosas como acrónimos en minúsculas, por lo que tal vez no sea la mejor idea en la mayoría de los casos
monokrome
Además, ¿realizó realmente GAMITG una edición solo para eliminar un espacio en blanco de una parte de la publicación que no contiene código? O_O
monokrome
por cierto, esto romperá acrónimos en mayúsculas, así que tengan cuidado con todos ustedes <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'
Fredrik A.
fuente
Hecho @Ram. También se incluyen ejemplos.
Fredrik A.
¿Cómo es esto mejor que la respuesta de 2009 ?
Dan Dascalescu
1
No es @DanDascalescu. Supongo que podría argumentar que substr/ substringes un poco más semántico en comparación con slice, pero eso es solo una cuestión de preferencia. Sin embargo, sí incluí ejemplos con las cadenas proporcionadas en la pregunta, que es un buen toque que no está presente en el ejemplo '09. Sinceramente, creo que todo se reduce a 15 años de mi deseo de karma en StackOverflow;)
Fredrik A.
34

Aquí hay una función llamada ucfirst () (abreviatura de "primera letra mayúscula"):

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

Puede poner en mayúscula una cadena llamando a ucfirst ("alguna cadena") , por ejemplo,

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

Funciona dividiendo la cuerda en dos pedazos. En la primera línea, saca firstLetter y luego, en la segunda línea, capitaliza firstLetter llamando a firstLetter.toUpperCase () y lo une con el resto de la cadena, que se encuentra llamando a str.substr (1) .

Puede pensar que esto fallaría para una cadena vacía, y de hecho en un lenguaje como C, tendría que atender esto. Sin embargo, en JavaScript, cuando toma una subcadena de una cadena vacía, solo recupera una cadena vacía.

Robert Wills
fuente
44
Use String.substring () o String.slice () ... No use substr (), está en desuso.
James
77
@ 999: ¿dónde dice que substr()está en desuso? No es , incluso ahora, tres años después, y mucho menos en 2009 cuando hiciste este comentario.
Dan Dascalescu el
substr()puede no estar marcado como obsoleto por ninguna implementación popular de ECMAScript (dudo que no vaya a desaparecer pronto), pero no es parte de la especificación de ECMAScript. La tercera edición de la especificación lo menciona en el anexo no normativo para "sugerir una semántica uniforme para tales propiedades sin hacer que las propiedades o su semántica formen parte de esta norma".
Peter Rust
2
Tener 3 métodos que hacen lo mismo ( substring, substry slice) es demasiado, IMO. Siempre lo uso sliceporque admite índices negativos, no tiene el comportamiento confuso de intercambio de argumentos y su API es similar a la slicede otros idiomas.
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 es una cadena de texto => Esta es una cadena de texto

Murat Kucukosman
fuente
20
Las expresiones regulares son excesivas para esto.
Anthony Sottile
+1, esto es lo que realmente estaba buscando. Sin embargo, hay un error menor, debería ser return.this.toLocaleLowerCase().replace(...
tomdemuyt
+1, encontré esta página buscando una versión javascript de phps ucfirst, que sospecho es la forma en que la mayoría de la gente la encuentra.
Benubird
@DanDascalescu Encontré esto útil, por lo que +1 utilitarismo y -1 retención anal. Incluyó un ejemplo, por lo que su función es clara.
Travis Webb
String.prototype.capitalize = function(){ return this.replace( /(^|\s)[a-z]/g , function(m){ return m.toUpperCase(); }); }; Refactorizo ​​un poco su código, solo necesita una primera coincidencia.
IGRACH
28
var str = "test string";
str = str.substring(0,1).toUpperCase() + str.substring(1);
MaxEcho
fuente
21

Verifique esta solución:

var stringVal = 'master';
stringVal.replace(/^./, stringVal[0].toUpperCase()); // returns Master 
Raju Bera
fuente
3
Esta debería ser la respuesta aceptada. La solución principal no debería usar un marco como el subrayado.
Adam McArthur
3
Ahorre algunas teclas;)stringVal.replace(/^./, stringVal[0].toUpperCase());
Alfredo Delgado
1
Regex no debe usarse donde no sea necesario. Es muy ineficiente y tampoco hace que el código sea más conciso. Además, stringVal[0]sería undefinedpara vacío stringVal, y como tal el intento de acceder a la propiedad .toUpperCase()arrojaría un error.
Przemek
20
yourString.replace(/^[a-z]/, function(m){ return m.toUpperCase() });

(Puede encapsularlo en una función o incluso agregarlo al prototipo String si lo usa con frecuencia).

Simón
fuente
55
Aunque esto tiene bastantes votos, esta es, con mucho, la solución más lenta publicada aquí. He reunido un poco más rápido con las respuestas más populares de esta publicación, aquí: forwebonly.com/…
Robin van Baalen
@RobinvanBaalen Su enlace ahora está roto. ¿Tienes uno actualizado?
Brad
1
Regexp es excesivo para esto, prefiera el más simple: str.charAt (0) .toUpperCase () + str.slice (1)
Simon
@Brad lamentablemente no
Robin van Baalen
Muchas veces, si quieres resolver tu problema con expresiones regulares, terminas con dos problemas.
Przemek
19

La ucfirstfunción funciona si lo haces así.

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

Gracias JP por la aclaración.

raphie
fuente
2
buen nombre para la función! Su nombre es idéntico al equivalente de PHP. En realidad, hay una biblioteca completa de funciones PHP escritas en JS; se llama PHP.js y se encuentra en http://phpjs.org
Hussam
11
One liner:string[0].toUpperCase() + string.substring(1)
dr.dimitru
@TarranJones aquí es un forro a prueba de balas:(string[0] || '').toUpperCase() + string.substring(1)
dr.dimitru
@ dr.dimitru: En lugar de idiomático (string[0] || '')podrías simplemente string.charAt(0).
Przemek
18

Puedes hacerlo en una línea como esta

string[0].toUpperCase() + string.substring(1)
QWERTY
fuente
Esta respuesta ya se dio en 2009 .
Dan Dascalescu
17
yourString.replace(/\w/, c => c.toUpperCase())

Encontré esta función de flecha más fácil. Reemplazar coincide con el primer carácter de letra ( \w) de su cadena y lo convierte a mayúsculas. Nada más lujoso necesario.

Lobo
fuente
1
Esta debería ser la respuesta aceptada, en cambio, es casi la última, ya que SO sigue otorgando preguntas obsoletas. Por cierto, es mejor usarlo /./por dos razones: /\w/omitirá todos los caracteres anteriores que no sean letras (por lo que @@ abc se convertirá en @@ Abc), y luego no funcionará con caracteres no latinos
Cristian Traìna