¿Cómo puedo poner en mayúscula la primera letra de cada palabra en una cadena usando JavaScript?


109

Estoy tratando de escribir una función que ponga en mayúscula la primera letra de cada palabra en una cadena (convirtiendo la cadena en caso de título).

Por ejemplo, cuando la entrada es "I'm a little tea pot", espero "I'm A Little Tea Pot"ser la salida. Sin embargo, la función regresa "i'm a little tea pot".

Este es mi codigo:

function titleCase(str) {
  var splitStr = str.toLowerCase().split(" ");

  for (var i = 0; i < splitStr.length; i++) {
    if (splitStr.length[i] < splitStr.length) {
      splitStr[i].charAt(0).toUpperCase();
    }

    str = splitStr.join(" ");
  }

  return str;
}

console.log(titleCase("I'm a little tea pot"));


Eso no parece que ponga en mayúscula la primera letra de una cadena. O quiere decir que desea poner en mayúscula cada palabra contenida en la cadena.
epascarello

2
Usted no se assigining su capitalización a su resultado, la splitStr[i].charAt(0).toUpperCase();va a void. Que tiene que hacersplitStr[i] = splitStr[i].charAt(0).toUpperCase() + splitStr[i].substring(1);
somethinghere

1
Debería decirnos primero. ¿Qué hay de malo en esa función? ¿Cuál es el resultado esperado y qué devuelve en su lugar?
user4642212

Esta función parece que intenta poner en mayúscula el primer carácter de cada palabra.
Halcyon

2
Como dice el título, estoy tratando de poner en mayúscula la primera letra de cada palabra en la cadena. No aprecio los votos negativos o la negatividad en un foro que se supone que es de apoyo por naturaleza. @somethinghere - Gracias por su respuesta.
slurrr

Respuestas:


160

No volverá a asignar sus cambios a la matriz, por lo que todos sus esfuerzos serán en vano. Prueba esto:

function titleCase(str) {
   var splitStr = str.toLowerCase().split(' ');
   for (var i = 0; i < splitStr.length; i++) {
       // You do not need to check if i is larger than splitStr length, as your for does that for you
       // Assign it back to the array
       splitStr[i] = splitStr[i].charAt(0).toUpperCase() + splitStr[i].substring(1);     
   }
   // Directly return the joined string
   return splitStr.join(' '); 
}

document.write(titleCase("I'm a little tea pot"));


@Halcyon Eso solo resultaría en una letra por cada palabra.
epascarello

13
En es6, puedes hacer esto, que se ve un poco mejor:myStr.toLowerCase().split(' ').map(word => word.charAt(0).toUpperCase() + word.substring(1)).join(' ');
Patrick Michaelsen

1
@PatrickMichaelsen De hecho, puedes. Sin embargo, no cambiaré la respuesta, es de 2015 y sé que los tiempos han cambiado, pero lo mantendré para la posteridad. Además, tampoco lo escribiría así :) Pero siéntete libre de publicar la tuya como tu propia respuesta, ¿supongo?
algo aquí

1
Sí, estoy de acuerdo, la respuesta actual está bien. Por eso lo puse en los comentarios, simplemente como referencia para los visitantes más nuevos.
Patrick Michaelsen

1
Ejecuté un punto de referencia de esta función contra 3 funciones de la competencia y encontré que era la de mayor rendimiento: menos de 1/3 del tiempo de ejecución del peor competidor (Chrome 73). jsben.ch/AkHgP
Michael Thompson

88

Estás haciendo una cosa muy fácil compleja. Puedes agregar esto en tu CSS:

.capitalize {
    text-transform: capitalize;
}

En JavaScript, puede agregar la clase a un elemento

 document.getElementById("element").className = "capitalize";

@epascarello No te entiendo, ¿qué me estás diciendo?
Marcos Pérez Gude

la pregunta es "¿Qué está mal con esta función?", de lo contrario, esto habría sido un duplicado de stackoverflow.com/questions/1026069/… o stackoverflow.com/questions/196972/…
Hacketo

1
gracias por la respuesta, pero estoy tratando de hacer esto usando javascript para practicar @ MarcosPérezGude
slurrr

1
Sí, es realmente versátil
Marcos Pérez Gude

3
Desafortunadamente, en algunos casos, si el valor es de 20 mm y usa mayúsculas, será de 20 mm. En algunos casos, javascript puede ser el único método.
Buts

73

Versión de ECMAScript 6 :

const toTitleCase = (phrase) => {
  return phrase
    .toLowerCase()
    .split(' ')
    .map(word => word.charAt(0).toUpperCase() + word.slice(1))
    .join(' ');
};

let result = toTitleCase('maRy hAd a lIttLe LaMb');
console.log(result);


1
También creo que falta, toLowerCase()desde el principio, en caso de que el usuario o la cadena sean casos mixtos.
ArchNoob

41

Creo que esta forma debería ser más rápida; porque no divide la cuerda y la vuelve a unir; simplemente usando regex.

var str = text.replace(/(^\w{1})|(\s{1}\w{1})/g, match => match.toUpperCase());

Explicacion :

  1. (^\w{1}): coincide con el primer carácter de la cadena
  2. |: o
  3. (\s{1}\w{1}): coincide con un carácter que vino después de un espacio
  4. g: emparejar todo
  5. match => match.toUpperCase (): reemplazar con can take function, entonces; reemplace la coincidencia con la coincidencia en mayúsculas

1
¡Mucho más limpio!
Cliff Hall

¿Por qué \s{1}? Yo diría \s+que funciona incluso con varios espacios entre palabras
Cristian Traìna

En mi caso; es exactamente 1 espacio, y sí; ¡deberia de funcionar!
nimeresam

Las cuerdas son inmutables. regex se dividirá y se unirá debajo del capó. En realidad, no hay forma de evitarlo.
bluegrounds

22

Si puede usar una biblioteca de terceros, Lodash tiene una función de ayuda para usted.

https://lodash.com/docs/4.17.3#startCase

_.startCase('foo bar');
// => 'Foo Bar'

_.startCase('--foo-bar--');
// => 'Foo Bar'

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

_.startCase('__FOO_BAR__');
// => 'FOO BAR'
<script src="https://cdn.jsdelivr.net/lodash/4.17.3/lodash.min.js"></script>


18

En ECMAScript 6, una respuesta de una línea usando la función de flecha:

const captialize = words => words.split(' ').map( w =>  w.substring(0,1).toUpperCase()+ w.substring(1)).join(' ')

3
¡Agradable! Puede utilizarlo w[0]para acortarlo aún más. A diferencia de las expresiones regulares, se puede ampliar fácilmente con CUALQUIER símbolo, pero no solo space. Quiero decir ( [ ", porque las letras también deben escribirse en mayúscula después de estos símbolos. ¡Gracias por tu solución!
Systems Rebooter

16

Shortest One Liner (también extremadamente rápido):

 text.replace(/(^\w|\s\w)/g, m => m.toUpperCase());

Explicación:

  • ^\w : primer carácter de la cadena
  • | : o
  • \s\w : primer carácter después del espacio en blanco
  • (^\w|\s\w) Captura el patrón.
  • g Bandera: coincide con todas las apariciones.

Si desea asegurarse de que el resto esté en minúsculas:

text.replace(/(^\w|\s\w)(\S*)/g, (_,m1,m2) => m1.toUpperCase()+m2.toLowerCase())

¡Esto es increíble! Las expresiones regulares son las mejores. ¿Puede colaborar más en lo que hace esta parte? m => m.toUpperCase()
marcin2x4

1
@ marcin2x4 mcoincide con el primer carácter, por lo que convierte el primer carácter en mayúscula.
pollos

10

Versión de ECMAScript 6 :

title
    .split(/ /g).map(word =>
        `${word.substring(0,1).toUpperCase()}${word.substring(1)}`)
    .join(" ");

6
Solo vi esto ahora y es bastante bueno, pero creo que debes unirte usando un en " "lugar de "", de lo contrario obtendrás una palabra importante, ¿no?
algo aquí

9

𝗙𝗮𝘀𝘁𝗲𝘀𝘁 𝗦𝗼𝗹𝘂𝘁𝗶𝗼𝗻 𝗙𝗼𝗿 𝗟𝗮𝘁𝗶𝗻-𝗜 𝗖𝗵𝗮𝗿𝗮𝗰𝘁𝗲𝗿𝘀

Simplemente puede usar una función de expresión regular para cambiar las mayúsculas de cada letra. Con las optimizaciones de V8 JIST, esto debería resultar rápido y eficiente en memoria.

// Only works on Latin-I strings
'tHe VeRy LOOong StRINg'.replace(/\b[a-z]|['_][a-z]|\B[A-Z]/g, function(x){return x[0]==="'"||x[0]==="_"?x:String.fromCharCode(x.charCodeAt(0)^32)})

O, en función:

// Only works for Latin-I strings
var fromCharCode = String.fromCharCode;
var firstLetterOfWordRegExp = /\b[a-z]|['_][a-z]|\B[A-Z]/g;
function toLatin1UpperCase(x){ // avoid frequent anonymous inline functions
    var charCode = x.charCodeAt(0);
    return charCode===39 ? x : fromCharCode(charCode^32);
}
function titleCase(string){
    return string.replace(firstLetterOfWordRegExp, toLatin1UpperCase);
}

Según este punto de referencia , el código es un 33% más rápido que la siguiente mejor solución en Chrome.


𝗗𝗲𝗺𝗼

<textarea id="input" type="text">I'm a little tea pot</textarea><br /><br />
<textarea id="output" type="text" readonly=""></textarea>
<script>
(function(){
    "use strict"
    var fromCode = String.fromCharCode;
    function upper(x){return x[0]==="'"?x:fromCode(x.charCodeAt(0) ^ 32)}
    (input.oninput = function(){
      output.value = input.value.replace(/\b[a-z]|['_][a-z]|\B[A-Z]/g, upper);
    })();
})();
</script>


Olvidó agregar retorno a su función como en: function autoCaps (string) {return string.replace (/ \ b [az] | \ B [AZ] / g, function (x) {return String.fromCharCode (x.charCodeAt (0) ^ 32);}); }
Archy

@Archy Gracias por su corrección. He realizado el cambio que propusiste.
Jack Giffin


6

También es una buena opción (especialmente si está usando freeCodeCamp ):

function titleCase(str) {
  var wordsArray = str.toLowerCase().split(/\s+/);
  var upperCased = wordsArray.map(function(word) {
    return word.charAt(0).toUpperCase() + word.substr(1);
  });
  return upperCased.join(" ");
}

5

Esta rutina manejará palabras con guiones y palabras con apóstrofo.

function titleCase(txt) {
    var firstLtr = 0;
    for (var i = 0;i < text.length;i++) {
        if (i == 0 &&/[a-zA-Z]/.test(text.charAt(i)))
            firstLtr = 2;
        if (firstLtr == 0 &&/[a-zA-Z]/.test(text.charAt(i)))
            firstLtr = 2;
        if (firstLtr == 1 &&/[^a-zA-Z]/.test(text.charAt(i))){
            if (text.charAt(i) == "'") {
                if (i + 2 == text.length &&/[a-zA-Z]/.test(text.charAt(i + 1)))
                    firstLtr = 3;
                else if (i + 2 < text.length &&/[^a-zA-Z]/.test(text.charAt(i + 2)))
                    firstLtr = 3;
            }
        if (firstLtr == 3)
            firstLtr = 1;
        else
            firstLtr = 0;
        }
        if (firstLtr == 2) {
            firstLtr = 1;
            text = text.substr(0, i) + text.charAt(i).toUpperCase() + text.substr(i + 1);
        }
        else {
            text = text.substr(0, i) + text.charAt(i).toLowerCase() + text.substr(i + 1);
        }
    }
}

titleCase("pAt o'Neil's");
// returns "Pat O'Neil's";

4
function LetterCapitalize(str) { 
  return str.split(" ").map(item=>item.substring(0,1).toUpperCase()+item.substring(1)).join(" ")
}

4

let cap = (str) => {
  let arr = str.split(' ');
  arr.forEach(function(item, index) {
    arr[index] = item.replace(item[0], item[0].toUpperCase());
  });

  return arr.join(' ');
};

console.log(cap("I'm a little tea pot"));

Versión de lectura rápida, consulte el punto de referencia http://jsben.ch/k3JVz ingrese la descripción de la imagen aquí


4

Sintaxis de ES6

const captilizeAllWords = (sentence) => {
  if (typeof sentence !== "string") return sentence;
  return sentence.split(' ')
    .map(word => word.charAt(0).toUpperCase() + word.slice(1))
    .join(' ');
}


captilizeAllWords('Something is going on here')

¿No debería reemplazarse word.slice (1) por word.slice (1) .toLowerCase () para asegurarse de que el resto no esté en mayúscula (en caso de que estuviera en la oración original)?
muni764

4

Puede usar la sintaxis JS moderna que puede hacer su vida mucho más fácil. Aquí está mi fragmento de código para el problema dado:

const capitalizeString = string => string.split(' ').map(item => item.replace(item.charAt(0), item.charAt(0).toUpperCase())).join(' ');
capitalizeString('Hi! i am aditya shrivastwa')


3

Por lo general, prefiero no usar regexp debido a la legibilidad y también trato de mantenerme alejado de los bucles. Creo que esto es legible.

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

3

La función a continuación no cambia ninguna otra parte de la cadena que intentar convertir todas las primeras letras de todas las palabras (es decir, por la definición de expresión regular \w+ ) a mayúsculas.

Eso significa que no necesariamente convierte palabras a Titlecase, pero hace exactamente lo que dice el título de la pregunta: "Poner en mayúscula la primera letra de cada palabra en una cadena - JavaScript"

  • No partas la cuerda
  • determinar cada palabra por la expresión regular \w+que es equivalente a[A-Za-z0-9_]+
    • aplica la función String.prototype.toUpperCase()solo al primer carácter de cada palabra.
function first_char_to_uppercase(argument) {
  return argument.replace(/\w+/g, function(word) {
    return word.charAt(0).toUpperCase() + word.slice(1);
  });
}

Ejemplos:

first_char_to_uppercase("I'm a little tea pot");
// "I'M A Little Tea Pot"
// This may look wrong to you, but was the intended result for me
// You may wanna extend the regex to get the result you desire, e.g., /[\w']+/

first_char_to_uppercase("maRy hAd a lIttLe LaMb");
// "MaRy HAd A LIttLe LaMb"
// Again, it does not convert words to Titlecase

first_char_to_uppercase(
  "ExampleX: CamelCase/UPPERCASE&lowercase,exampleY:N0=apples"
);
// "ExampleX: CamelCase/UPPERCASE&Lowercase,ExampleY:N0=Apples"

first_char_to_uppercase("…n1=orangesFromSPAIN&&n2!='a sub-string inside'");
// "…N1=OrangesFromSPAIN&&N2!='A Sub-String Inside'"

first_char_to_uppercase("snake_case_example_.Train-case-example…");
// "Snake_case_example_.Train-Case-Example…"
// Note that underscore _ is part of the RegEx \w+

first_char_to_uppercase(
  "Capitalize First Letter of each word in a String - JavaScript"
);
// "Capitalize First Letter Of Each Word In A String - JavaScript"

Edite 2019-02-07: Si desea el título real (es decir, solo la primera letra en mayúscula, todas las demás en minúsculas):

function titlecase_all_words(argument) {
  return argument.replace(/\w+/g, function(word) {
    return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
  });
}

Ejemplos que muestran ambos:

test_phrases = [
  "I'm a little tea pot",
  "maRy hAd a lIttLe LaMb",
  "ExampleX: CamelCase/UPPERCASE&lowercase,exampleY:N0=apples",
  "…n1=orangesFromSPAIN&&n2!='a sub-string inside'",
  "snake_case_example_.Train-case-example…",
  "Capitalize First Letter of each word in a String - JavaScript"
];
for (el in test_phrases) {
  let phrase = test_phrases[el];
  console.log(
    phrase,
    "<- input phrase\n",
    first_char_to_uppercase(phrase),
    "<- first_char_to_uppercase\n",
    titlecase_all_words(phrase),
    "<- titlecase_all_words\n "
  );
}

// I'm a little tea pot <- input phrase
// I'M A Little Tea Pot <- first_char_to_uppercase
// I'M A Little Tea Pot <- titlecase_all_words

// maRy hAd a lIttLe LaMb <- input phrase
// MaRy HAd A LIttLe LaMb <- first_char_to_uppercase
// Mary Had A Little Lamb <- titlecase_all_words

// ExampleX: CamelCase/UPPERCASE&lowercase,exampleY:N0=apples <- input phrase
// ExampleX: CamelCase/UPPERCASE&Lowercase,ExampleY:N0=Apples <- first_char_to_uppercase
// Examplex: Camelcase/Uppercase&Lowercase,Exampley:N0=Apples <- titlecase_all_words

// …n1=orangesFromSPAIN&&n2!='a sub-string inside' <- input phrase
// …N1=OrangesFromSPAIN&&N2!='A Sub-String Inside' <- first_char_to_uppercase
// …N1=Orangesfromspain&&N2!='A Sub-String Inside' <- titlecase_all_words

// snake_case_example_.Train-case-example… <- input phrase
// Snake_case_example_.Train-Case-Example… <- first_char_to_uppercase
// Snake_case_example_.Train-Case-Example… <- titlecase_all_words

// Capitalize First Letter of each word in a String - JavaScript <- input phrase
// Capitalize First Letter Of Each Word In A String - JavaScript <- first_char_to_uppercase
// Capitalize First Letter Of Each Word In A String - Javascript <- titlecase_all_words

3
function titleCase(str) {

    var myString = str.toLowerCase().split(' ');
    for (var i = 0; i < myString.length; i++) {
        var subString = myString[i].split('');
        for (var j = 0; j < subString.length; j++) {
            subString[0] = subString[0].toUpperCase();
        }
        myString[i] = subString.join('');
    }

    return myString.join(' ');
}

1
Agregue algunos comentarios a su respuesta.
HDJEMAI

3

O se puede hacer usando replace () y reemplazar la primera letra de cada palabra con su "upperCase".

function titleCase(str) {
    return str.toLowerCase().split(' ').map(function(word) {
               return word.replace(word[0], word[0].toUpperCase());
           }).join(' ');
}

titleCase("I'm a little tea pot");

2

Así es como puede hacerlo con la mapfunción básicamente, hace lo mismo que la respuesta aceptada pero sin el for-loop. Por lo tanto, le ahorra algunas líneas de código.

function titleCase(text) {
  if (!text) return text;
  if (typeof text !== 'string') throw "invalid argument";

  return text.toLowerCase().split(' ').map(value => {
    return value.charAt(0).toUpperCase() + value.substring(1);
  }).join(' ');
}

console.log(titleCase("I'm A little tea pot"));


2

A continuación se muestra otra forma de poner en mayúscula el primer alfabeto de cada palabra en una cadena.

Cree un método personalizado para un objeto String utilizando prototype.

String.prototype.capitalize = function() {
    var c = '';
    var s = this.split(' ');
    for (var i = 0; i < s.length; i++) {
        c+= s[i].charAt(0).toUpperCase() + s[i].slice(1) + ' ';
    }
    return c;
}
var name = "john doe";
document.write(name.capitalize());

1

Una reescritura más compacta (y moderna) de la solución propuesta de @ somethingthere:

let titleCase = (str => str.toLowerCase().split(' ').map(
                c => c.charAt(0).toUpperCase() + c.substring(1)).join(' '));
    
document.write(titleCase("I'm an even smaller tea pot"));


1

Código crudo:

function capi(str) {
    var s2 = str.trim().toLowerCase().split(' ');
    var s3 = [];
    s2.forEach(function(elem, i) {
        s3.push(elem.charAt(0).toUpperCase().concat(elem.substring(1)));
    });
    return s3.join(' ');
}
capi('JavaScript string exasd');

Debería proporcionar un poco más de detalles (¿cuál fue el problema?)
Hering

1

Usé replace()con una expresión regular:

function titleCase(str) {

  var newStr = str.toLowerCase().replace(/./, (x) => x.toUpperCase()).replace(/[^']\b\w/g, (y) => y.toUpperCase());

  console.log(newStr);
}

titleCase("I'm a little tea pot")

1

Aquí va una solución completa y sencilla:

String.prototype.replaceAt=function(index, replacement) {
        return this.substr(0, index) + replacement+ this.substr(index
  + replacement.length);
}
var str = 'k j g           u              i l  p';
function capitalizeAndRemoveMoreThanOneSpaceInAString() {
    for(let i  = 0; i < str.length-1; i++) {
        if(str[i] === ' ' && str[i+1] !== '')
            str = str.replaceAt(i+1, str[i+1].toUpperCase());
    }
    return str.replaceAt(0, str[0].toUpperCase()).replace(/\s+/g, ' ');
}
console.log(capitalizeAndRemoveMoreThanOneSpaceInAString(str));

¿Por qué modifica el String.prototype cada vez que se llama a este método? En todo caso, debe hacerlo una vez , y preferiblemente nunca toque los prototipos de incorporados. Es un poco no-no ...
algo aquí

0

Por favor revise el código a continuación.

function titleCase(str) {
  var splitStr = str.toLowerCase().split(' ');
  var nstr = ""; 
  for (var i = 0; i < splitStr.length; i++) {
    nstr +=  (splitStr[i].charAt(0).toUpperCase()+ splitStr[i].slice(1) + " 
    ");
  }
  console.log(nstr);
}

var strng = "this is a new demo for checking the string";
titleCase(strng);

2
Gracias por este fragmento de código, que puede proporcionar ayuda inmediata y limitada. Una explicación adecuada mejoraría enormemente su valor a largo plazo al mostrar por qué es una buena solución al problema y lo haría más útil para futuros lectores con otras preguntas similares. Por favor, editar su respuesta a añadir un poco de explicación, incluyendo los supuestos realizados.
iBug

0

A partir de ECMA2017 o ES8

const titleCase = (string) => {
  return string
    .split(' ')
    .map(word => word.substr(0,1).toUpperCase() + word.substr(1,word.length))
    .join(' ');
};

let result = titleCase('test test test');
console.log(result);

Explicación:
1. Primero, pasamos la cadena "test test test" a nuestra función "titleCase".
2. Dividimos una cadena en base al espacio para que el resultado de la primera función "dividir" sea ["prueba", "prueba", "prueba"]
3. Cuando obtuvimos una matriz, usamos la función de mapa para manipular cada palabra en la matriz. Escribimos en mayúscula el primer carácter y le agregamos el carácter restante.
4. En el último, unimos la matriz usando el espacio mientras dividimos la cadena por sapce.


Creo que te falta algo al principio antes de dividirte y eso es toLowerCase().
ArchNoob

@ArchNoob, sí, podemos agregar toLowerCase () antes de dividir. Pero depende totalmente del caso de uso, por ejemplo, si queremos una salida de "Prueba de prueba" para la entrada de "prueba de prueba", en este caso, no podemos agregar toLowerCase ().
Pulkit Aggarwal

0

function titleCase(str) {
  //First of all, lets make all the characters lower case
  let lowerCaseString = "";
  for (let i = 0; i < str.length; i++) {
    lowerCaseString = lowerCaseString + str[i].toLowerCase();
  }
  //Now lets make the first character in the string and the character after the empty character upper case and leave therest as it is
  let i = 0;
  let upperCaseString = "";
  while (i < lowerCaseString.length) {
    if (i == 0) {
      upperCaseString = upperCaseString + lowerCaseString[i].toUpperCase();
    } else if (lowerCaseString[i - 1] == " ") {
      upperCaseString = upperCaseString + lowerCaseString[i].toUpperCase();
    } else {
      upperCaseString = upperCaseString + lowerCaseString[i];
    }
    i = i + 1;
  }
  console.log(upperCaseString);

  return upperCaseString;
}

titleCase("hello woRLD");


0

Aquí he usado tres funciones toLowerCase(), toUpperCase()yreplace(regex,replacer)

function titleCase(str) { 
     return str.toLowerCase().replace(/^(\w)|\s(\w)/g, (grp) => grp.toUpperCase()); 
}

titleCase("I'm a little tea pot");

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.