Capitalizar palabras en cadena

183

¿Cuál es el mejor enfoque para capitalizar palabras en una cadena?

vsync
fuente
66
Si es para mostrar, use CSS. text-transform:capitalize;.
kennytm
3
Esto se debe utilizar para establecer el atributo "título" en los elementos DOM. sin CSS :)
vsync
1
Además, hice esta pregunta, aunque conozco la solución, solo porque intenté buscarla en este sitio web y no pude encontrar una solución decente, así que la agregué por el bien de la documentación.
vsync
1
@KennyTM: text-transform realmente no capitalizaría los valores de los archivos de formulario, todos los valores se presentarían en mayúscula, pero se enviarían al servidor tal como están.
Marco Demaio
8
@Marco: Sí, por eso dije "Si es para mostrar".
kennytm

Respuestas:

287
/**
 * Capitalizes first letters of words in string.
 * @param {string} str String to be modified
 * @param {boolean=false} lower Whether all other letters should be lowercased
 * @return {string}
 * @usage
 *   capitalize('fix this string');     // -> 'Fix This String'
 *   capitalize('javaSCrIPT');          // -> 'JavaSCrIPT'
 *   capitalize('javaSCrIPT', true);    // -> 'Javascript'
 */
const capitalize = (str, lower = false) =>
  (lower ? str.toLowerCase() : str).replace(/(?:^|\s|["'([{])+\S/g, match => match.toUpperCase());
;

  • corrige la solución de Marco Demaio donde la primera letra con un espacio anterior no está en mayúscula.
capitalize(' javascript'); // -> ' Javascript'
  • puede manejar símbolos nacionales y letras acentuadas.
capitalize('бабушка курит трубку');  // -> 'Бабушка Курит Трубку'
capitalize('località àtilacol')      // -> 'Località Àtilacol'
  • puede manejar citas y llaves.
capitalize(`"quotes" 'and' (braces) {braces} [braces]`);  // -> "Quotes" 'And' (Braces) {Braces} [Braces]
disgustado
fuente
44
regexp funciona como "Tomar todos los caracteres que no sean espacios en blanco (\ S) de pie justo al comienzo de la cadena (^) o después de cualquier carácter de espacio en blanco (\ s) y ponerlos en mayúscula"
desapareció
3
Una pequeña mejora para manejar las cadenas en mayúsculas :) ** String.prototype.capitalize = function () {return this.toLowerCase (). Replace (/ (?: ^ | \ S) \ S / g, function (a) {return a.toUpperCase ();}); }; **
SuryaPavan
1
Por favor no altere los prototipos de objetos existentes.
Ascherer
1
@ Dr.X, véase el complemento, 'CHECK THIS OUT'.capitalize(true) -> "Check This Out". trueParámetro mental .
desapareció el
1
@ SeaWarrior404, tienes razón, actualicé mi respuesta con la sintaxis es6, agregué jsdoc y algún tratamiento de puntuación
disgustado el
216

La implementación más corta para capitalizar palabras dentro de una cadena es la siguiente usando las funciones de flecha de ES6:

'your string'.replace(/\b\w/g, l => l.toUpperCase())
// => 'Your String'

Implementación compatible con ES5:

'your string'.replace(/\b\w/g, function(l){ return l.toUpperCase() })
// => 'Your String'

La expresión regular básicamente coincide con la primera letra de cada palabra dentro de la cadena dada y transforma solo esa letra en mayúscula:

  • \ b coincide con un límite de palabra (el principio o el final de la palabra);
  • \ w coincide con el siguiente meta-carácter [a-zA-Z0-9].

Para caracteres no ASCII, consulte esta solución en su lugar

'ÿöur striñg'.replace(/(^|\s)\S/g, l => l.toUpperCase())

Esta expresión regular coincide con la primera letra y todas las letras que no son espacios en blanco precedidas por espacios en blanco dentro de la cadena dada y transforma solo esa letra en mayúsculas:

  • \ s coincide con un carácter de espacio en blanco
  • \ S coincide con un carácter que no es un espacio en blanco
  • (x | y) coincide con cualquiera de las alternativas especificadas

Un grupo no capturador podría haberse utilizado aquí de la siguiente manera, /(?:^|\s)\S/gaunqueg bandera dentro de nuestra expresión regular no capturará subgrupos por diseño de todos modos.

¡Salud!

Ivo
fuente
1
¿Podría explicar en la respuesta cómo funciona la expresión regular? (el significado de cada pieza)
vsync
2
Lo seleccionaré como la respuesta si la explicación está dentro de él y no como un comentario que uno pueda perderse.
vsync
2
Esto no parece funcionar para los caracteres nórdicos ä, ö y å. Por ejemplo päijät-hämese hacePäIjäT-HäMe
Markus Meskanen
1
Esta solución no es buena para el contenido internacional que contiene caracteres diacríticos / no latinos. EisbäRenes un resultado, por ejemplo.
Daniel B.
3
El ejemplo de @MarkusMeskanen debería cambiar a Päijät-Häme, pero al menos en el espacio en blanco de Chrome no incluye el guión (-), por lo que la segunda parte del nombre no está en mayúscula. Se puede arreglar como /(^|\s|-)\S/g.
MiRin
34
function capitalize(s){
    return s.toLowerCase().replace( /\b./g, function(a){ return a.toUpperCase(); } );
};

capitalize('this IS THE wOrst string eVeR');

salida: "Esta es la peor cadena de la historia"

Actualizar:

Parece que esta solución reemplaza a la mía: https://stackoverflow.com/a/7592235/104380

vsync
fuente
cuidado con que parece que tu función capitaliza erróneamente también las letras acentuadas, mira mi respuesta: stackoverflow.com/questions/2332811/capitalize-words-in-string/ ... También lo escribí.
Marco Demaio
9
No me gusta la creación de prototipos, tiene el potencial de crear colisiones si alguien más está usando el mismo nombre para crear un prototipo de cadena.
vsync
15

La respuesta proporcionada por vsync funciona siempre que no tenga letras acentuadas en la cadena de entrada.

No sé la razón, pero aparentemente las \bcoincidencias en regexp también coinciden con letras acentuadas (probadas en IE8 y Chrome), por lo que una cadena como "località"se capitalizaría erróneamente convertida en"LocalitÀ" (la àletra se capitaliza porque la expresión regular piensa que es un límite de palabra)

Una función más general que funciona también con letras acentuadas es esta:

String.prototype.toCapitalize = function()
{ 
   return this.toLowerCase().replace(/^.|\s\S/g, function(a) { return a.toUpperCase(); });
}

Puedes usarlo así:

alert( "hello località".toCapitalize() );
Marco Demaio
fuente
1
" javascript".toCapitalize() -> " javascript"
desapareció el
2
A QUIEN PUEDE PREOCUPAR: la respuesta desvalorizada stackoverflow.com/questions/2332811/capitalize-words-in-string/… es ahora la mejor respuesta aquí.
Marco Demaio
4

Como todos le han dado la respuesta de JavaScript que solicitó, agregaré la propiedad CSS text-transform: capitalize hará exactamente esto.

Me doy cuenta de que esto podría no ser lo que estás pidiendo, no nos has dado nada del contexto en el que estás ejecutando esto, pero si es solo para una presentación, definitivamente elegiría la alternativa CSS.

David Hedlund
fuente
KennyTM te ganó. Revise su comentario en la sección de preguntas. :-)
Buhake Sindi
Sí, conozco este atributo CSS, pero lo necesito para el atributo de título a elementos dom, y no tiene CSS, como ya sabrán.
vsync
4

John Resig (de jQuery fame) portó un script en perl, escrito por John Gruber, a JavaScript. Este script capitaliza de una manera más inteligente, no capitaliza palabras pequeñas como 'de' y 'y' por ejemplo.

Puede encontrarlo aquí: Capitalización de títulos en JavaScript

meouw
fuente
4

Usando JavaScript y HTML

String.prototype.capitalize = function() {
  return this.replace(/(^|\s)([a-z])/g, function(m, p1, p2) {
    return p1 + p2.toUpperCase();
  });
};
<form name="form1" method="post">
  <input name="instring" type="text" value="this is the text string" size="30">
  <input type="button" name="Capitalize" value="Capitalize >>" onclick="form1.outstring.value=form1.instring.value.capitalize();">
  <input name="outstring" type="text" value="" size="30">
</form>

Básicamente, puedes hacer string.capitalize() y capitalizará cada 1ra letra de cada palabra.

Fuente: http://www.mediacollege.com/internet/javascript/text/case-capitalize.html

Buhake Sindi
fuente
1
No soy fanático de la creación de prototipos de esta manera, porque mis scripts a veces son incrustaciones de terceros en otros sitios web, y eso puede causar problemas para manipular objetos globales como "String" ... por lo que prefiero "utilizarlos".
vsync
1
Esa es la belleza del prototipo (no el prototipo que descargas). Es estándar en javascript y funciona en todos los navegadores.
Buhake Sindi
Sospecho que puede causar problemas si alguien más ha realizado un prototipo de su propio String.prototype.capitalize, y lo anularé accidentalmente.
vsync
1
@vsync, siempre puede verificar haciendo esto. if (object.capitalize) {...} else {String.prototype.capitalize = function()....}donde objeto es de tipo String. Entonces, es bastante simple en realidad.
Buhake Sindi
4

La respuesta de Ivo es buena, pero prefiero no coincidir \wporque no hay necesidad de capitalizar 0-9 y AZ. Podemos ignorarlos y solo coincidir en az.

'your string'.replace(/\b[a-z]/g, match => match.toUpperCase())
// => 'Your String'

Es el mismo resultado, pero creo que más claro en términos de código autodocumentado.

Gran dinero
fuente
Esto fallar por carta de no Inglés: "Är Toaletten". Su respuesta, contestó años después se había proporcionado muy buenos, no contribuye a la discusión ..
VSYNC
@vsync que parece bastante duro. Es una optimización de la respuesta aceptada. /\b\w/gtambién falla para letras que no están en inglés. No todos tratan con caracteres Unicode, y esto ayudará a aquellos que quieran no hacerlo.
Big Money
1
Muy bien ... No creo que debas usar esto en lugar de la respuesta principal solo porque no necesitas ningún otro idioma además del inglés. Esa no es una justificación suficientemente buena, ya que no hay penalización por hacerlo para todos los caracteres ASCII como se dijo en la pregunta principal
vsync
3

Si está usando lodash en su aplicación JavaScript, puede usar _.capitalize :

console.log( _.capitalize('ÿöur striñg') );
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js"></script>

vicke4
fuente
3

Una forma concisa de hacerlo en ES6 podría verse así.

const capitalizeFirstLetter = s => s.charAt(0).toUpperCase() + s.slice(1)

Esto solo pone en mayúscula la primera letra y no afecta el resto de la carcasa de la oración.

Otman Zaib
fuente
2

Mi solución:

String.prototype.toCapital = function () {
    return this.toLowerCase().split(' ').map(function (i) {
        if (i.length > 2) {
            return i.charAt(0).toUpperCase() + i.substr(1);
        }

        return i;
    }).join(' ');
};

Ejemplo:

'álL riGht'.toCapital();
// Returns 'Áll Right'
Erick Tatsui
fuente
Pruebe varios métodos y su solución es la más eficiente y respeta los acentos del nombre jsbench.me/urjeu9wvql
nasatome
Esto no funciona: 'a áAA. bb . bbb .cc .d'.toCapital();=>a Áaa. bb . Bbb .cc .d
vsync
Lo hice para no considerar palabras con menos de 2 letras, como "de", "como".
Erick Tatsui
1

Esto debería cubrir la mayoría de los casos de uso básicos.

const capitalize = (str) => {
    if (typeof str !== 'string') {
      throw Error('Feed me string')
    } else if (!str) {
      return ''
    } else {
      return str
        .split(' ')
        .map(s => {
            if (s.length == 1 ) {
                return s.toUpperCase()
            } else {
                const firstLetter = s.split('')[0].toUpperCase()
                const restOfStr = s.substr(1, s.length).toLowerCase()
                return firstLetter + restOfStr
            }     
        })
        .join(' ')
    }
}


capitalize('THIS IS A BOOK') // => This Is A Book
capitalize('this is a book') // => This Is A Book
capitalize('a 2nd 5 hour boOk thIs weEk') // => A 2nd 5 Hour Book This Week

Editar: Legibilidad mejorada de mapeo.

Gotas
fuente
¿Puede explicar por qué cree que su respuesta es mejor que otras de hace muchos años?
vsync
¿Puedes explicar por qué crees que quise decir que mi respuesta es la mejor o mejor que otras? No mencioné eso, es simplemente diferente. Además, no te vi dejar este comentario en otras publicaciones, así que realmente no lo entiendo. Pero para empezar: usa las características modernas de js (desestructuración, flecha gruesa, retorno implícito), no usa regx y es un enfoque más funcional del problema. También tiene un manejo de errores muy básico y devuelve una cadena vacía si la pasa (para mí eso fue importante).
Cae el
está bien ser diferente, pero tiene que ser mejor o igual que otras respuestas, y parece ser ... ilegible y ciertamente nadie pondría en el código de producción porque nadie podría entenderlo
vsync
Ahhh ok, entonces 50% de las soluciones aquí, ¿qué string de parche de mono realmente pondrás en producción? ¿O tal vez expresiones de expresiones regulares enrevesadas? Es mucho más fácil razonar con ellos, ¿verdad? Imho absolutamente no! También decir que nadie entenderá esto es una declaración bastante subjetiva. También para esto dijiste que es un fragmento de código triturado (más características, pero ese no es el caso aquí). ¿Cómo es que eso se tritura y mi solución nadie lo entenderá? No hay forma de desenredar esas expresiones regulares sin perder horas.
Gotas el
Ese código fue escrito por el propio Sr. Resig y no debe ser cuestionado. Usted, por otro lado, carece de credibilidad debido a su anonimato. En cualquier caso, una solución Regex es más corta, se ejecuta mucho más rápido y también es fácil de leer por cualquiera que haya aprendido los conceptos básicos de Regex. Apenas hay mucho que "desenredar" en este: /\b\w/g...
VSYNC
1

Esta solución no utiliza expresiones regulares, admite caracteres acentuados y también es compatible con casi todos los navegadores.

function capitalizeIt(str) {
    if (str && typeof(str) === "string") {
        str = str.split(" ");    
        for (var i = 0, x = str.length; i < x; i++) {
            if (str[i]) {
                str[i] = str[i][0].toUpperCase() + str[i].substr(1);
            }
        }
        return str.join(" ");
    } else {
        return str;
    }
}    

Uso:

console.log (capitalizeIt ('çao 2nd dentro del programa Javascript'));

Salida:

Çao 2nd Inside Javascript Program

Nabarag Paul
fuente
1
De esta forma, se consumen muchos recursos de CPU. JavaScript no cambia los valores primitivos, eso implica la creación de uno nuevo cada vez que se realiza una operación. Es mejor usar funciones nativas como "reemplazar", ejemplo gratia.
Daniel Bandeira
0

http://www.mediacollege.com/internet/javascript/text/case-capitalize.html es una de las muchas respuestas disponibles.

Google puede ser todo lo que necesita para tales problemas.

Un enfoque ingenuo sería dividir la cadena por espacios en blanco, poner en mayúscula la primera letra de cada elemento de la matriz resultante y unirla nuevamente. Esto deja solo las mayúsculas existentes (por ejemplo, HTML sigue siendo HTML y no se convierte en algo tonto como Html). Si no desea ese efecto, convierta toda la cadena en minúsculas antes de dividirla.

Alan ciruela
fuente
0

Este código capitaliza las palabras después del punto:

function capitalizeAfterPeriod(input) { 
    var text = '';
    var str = $(input).val();
    text = convert(str.toLowerCase().split('. ')).join('. ');
    var textoFormatado = convert(text.split('.')).join('.');
    $(input).val(textoFormatado);
}

function convert(str) {
   for(var i = 0; i < str.length; i++){
      str[i] = str[i].split('');
      if (str[i][0] !== undefined) {
         str[i][0] = str[i][0].toUpperCase();
      }
      str[i] = str[i].join('');
   }
   return str;
}
Flavio
fuente
0

Me gusta ir con un proceso fácil. Primero cambie la cadena a Array para una iteración fácil, luego, usando la función de mapa, cambie cada palabra como desee.

function capitalizeCase(str) {
    var arr = str.split(' ');
    var t;
    var newt;
    var newarr = arr.map(function(d){
        t = d.split('');
        newt = t.map(function(d, i){
                  if(i === 0) {
                     return d.toUpperCase();
                    }
                 return d.toLowerCase();
               });
        return newt.join('');
      });
    var s = newarr.join(' ');
    return s;
  }
Mritunjay Upadhyay
fuente
0

Jquery o Javascipt no proporcionan un método integrado para lograr esto.

La transformación de prueba CSS (text-transform: capitalize;) realmente no capitaliza los datos de la cadena, pero muestra una representación en mayúscula en la pantalla.

Si está buscando una forma más legítima de lograr esto en el nivel de datos usando vanillaJS simple, use esta solución =>

var capitalizeString = function (word) {    
    word = word.toLowerCase();
    if (word.indexOf(" ") != -1) { // passed param contains 1 + words
        word = word.replace(/\s/g, "--");
        var result = $.camelCase("-" + word);
        return result.replace(/-/g, " ");
    } else {
    return $.camelCase("-" + word);
    }
}
siwalikm
fuente
0

Utilizar este:

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

let str = 'text';
document.querySelector('#demo').innerText = str.toTitleCase();
<div class = "app">
  <p id = "demo"></p>
</div>

Sanjay
fuente
0

Puede usar lo siguiente para poner en mayúscula las palabras en una cadena:

function capitalizeAll(str){

    var partes = str.split(' ');

    var nuevoStr = ""; 

    for(i=0; i<partes.length; i++){
    nuevoStr += " "+partes[i].toLowerCase().replace(/\b\w/g, l => l.toUpperCase()).trim(); 
    }    

    return nuevoStr;

}
Marcos Torres
fuente
0

También hay locutus: https://locutus.io/php/strings/ucwords/ que lo define de esta manera:

function ucwords(str) {
  //  discuss at: http://locutus.io/php/ucwords/
  // original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
  // improved by: Waldo Malqui Silva (http://waldo.malqui.info)
  // improved by: Robin
  // improved by: Kevin van Zonneveld (http://kvz.io)
  // bugfixed by: Onno Marsman (https://twitter.com/onnomarsman)
  // bugfixed by: Cetvertacov Alexandr (https://github.com/cetver)
  //    input by: James (http://www.james-bell.co.uk/)
  //   example 1: ucwords('kevin van  zonneveld')
  //   returns 1: 'Kevin Van  Zonneveld'
  //   example 2: ucwords('HELLO WORLD')
  //   returns 2: 'HELLO WORLD'
  //   example 3: ucwords('у мэри был маленький ягненок и она его очень любила')
  //   returns 3: 'У Мэри Был Маленький Ягненок И Она Его Очень Любила'
  //   example 4: ucwords('τάχιστη αλώπηξ βαφής ψημένη γη, δρασκελίζει υπέρ νωθρού κυνός')
  //   returns 4: 'Τάχιστη Αλώπηξ Βαφής Ψημένη Γη, Δρασκελίζει Υπέρ Νωθρού Κυνός'

  return (str + '').replace(/^(.)|\s+(.)/g, function ($1) {
    return $1.toUpperCase();
  });
};
geodésico
fuente
0

Yo usaría regex para este propósito:

myString = '  this Is my sTring.  ';
myString.trim().toLowerCase().replace(/\w\S*/g, (w) => (w.replace(/^\w/, (c) => c.toUpperCase())));
Título Newt
fuente