Converti la stringa in maiuscolo / minuscolo con JavaScript


549

Esiste un modo semplice per convertire una stringa in case del titolo? Ad esempio john smithdiventa John Smith. Non sto cercando qualcosa di complicato come la soluzione di John Resig , solo (si spera) una specie di una o due linee.


Esistono vari metodi, abbiamo alcune statistiche sulle prestazioni?
theAnubhav

Per favore, chiedi questa breve risposta stackoverflow.com/a/57689168/10373693 Spero che sarà la risposta che stai cercando.
Abhishek Kumar,

Risposte:


740

Prova questo:

    function toTitleCase(str) {
        return str.replace(
            /\w\S*/g,
            function(txt) {
                return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
            }
        );
    }
<form>
Input:
<br /><textarea name="input" onchange="form.output.value=toTitleCase(this.value)"  onkeyup="form.output.value=toTitleCase(this.value)"></textarea>
<br />Output:
<br /><textarea name="output" readonly onclick="select(this)"></textarea>
</form>


14
Qualcuno potrebbe spiegare, perché \w\S*viene utilizzato, al posto di \w+o \w*per esempio? Non lo so, perché vorresti includere qualsiasi cosa tranne gli spazi e quindi cambiare Jim-Bob in Jim-bob .
martinczerwi,

5
@martinCzerwi ha \w\S*anche causato il Jim-bobproblema da parte nostra. Usando \w*risolto questo.
Bouke,

14
/([^\W_]+[^\s-]*) */grisolve il Jim-Bobproblema, ovvero:jim-bob --> Jim-Bob
recursion.ninja,

15
Se jim-bob --> Jim-Bobè il tuo desiderio, probabilmente dovresti farlo /\b\w+/g. Esempio:str.replace(/\b\w+/g,function(s){return s.charAt(0).toUpperCase() + s.substr(1).toLowerCase();});
vol7ron,

3
\w\S*viene utilizzato al posto \w+o meno in \w*modo che parole come Don'tnon vengano modificate Don'T, ma come altri hanno sottolineato \w\S*causa problemi con parole sillabate.
doubleDown

198

Un modo leggermente più elegante, adattando la funzione di Greg Dean:

String.prototype.toProperCase = function () {
    return this.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();});
};

Chiamalo come:

"pascal".toProperCase();

3
Tenere a mente se si dispone di un utente con un trattino in loro nome e entrano Jo-Ann Smith, questo codice convertirli Jo-ann Smith(notare il minuscolo ain Ann).
dbau,

18
@daniellmb Perché non dovrebbe alterare il prototipo String? Penso che sia una buona soluzione. Pensa alle classi aperte ruby, è perfettamente valido aggiungere funzioni alle classi esistenti ed è ampiamente accettato.
marco-fiset,

97
@ marco-fiset Perché non gioca bene con gli altri! Le cose brutte accadono quando si hanno 2 librerie che tentano entrambe di modificare oggetti JavaScript nativi con modifiche incompatibili. Immagina se jQuery e Google Maps seguissero questo modello di progettazione, non avresti potuto avere entrambi sulla stessa pagina.
daniellmb,

5
@daniellmb Un punto eccellente. Il prefisso del nome del metodo dovrebbe aiutare a evitarlo, così come il metodo non enumerabile.
mikemaccana,

60
Sento che l'istruzione "non modificare oggetti JavaScript nativi" è come "non usare mai goto" o "eval is evil". Ci sono molti casi in cui è ok. Se hai il controllo completo sul tuo progetto e ovviamente non hai intenzione di rilasciarlo come libreria, non vedo problemi con questo metodo.
FoxMulder900,

175

Prova ad applicare lo stile CSS di trasformazione del testo ai tuoi controlli.

per esempio: (text-transform: capitalize);

Utilizzare un approccio JS solo quando assolutamente necessario.


36
-1. Questo CSS funziona, ma non funziona come la maggior parte della gente si aspetta perché se il testo inizia come maiuscolo, non c'è alcun effetto. webmasterworld.com/forum83/7506.htm
whitneyland,

2
@Akshar: una regola minuscola sarebbe sostituita da una regola maiuscola. Poiché css non modifica il contenuto di origine, l'effetto è che la regola minuscola viene rimossa (lasciando il contenuto di origine in maiuscolo) e quindi verrà applicata la regola del titolo (senza fare nulla).
dokkaebi,

42
JS viene utilizzato al di fuori dei browser.
mikemaccana,

4
La domanda era: "Esiste un modo semplice per convertire una stringa in maiuscolo / minuscolo?" . Questa risposta non converte una stringa. Questo è uno stile applicato sopra una stringa.
KingPuppy,

Se vuoi che i dati nel tuo database siano puliti, in modo che possano essere utilizzati in modo pulito quando passi a servizi di terze parti o esportati in CSV, CSS non è davvero un'opzione. Il CSS è destinato ai cosmetici e sebbene sia cresciuto molto nel corso degli anni e puoi usarlo per risolvere questo tipo di problemi, la soluzione rimane cosmetica e non risolve il problema di fondo.
Adam Reis,

118

Ecco la mia versione, IMO è anche facile da capire ed elegante.

var str = "foo bar baz"

console.log(

str.split(' ')
   .map(w => w[0].toUpperCase() + w.substr(1).toLowerCase())
   .join(' ')

)
// returns "Foo Bar Baz"


3
In alternativa, è possibile minuscolare la sottostringa nella mappatura:str.split(' ').map(i => i[0].toUpperCase() + i.substring(1).toLowerCase()).join(' ')
Dave Land

5
Non sono d'accordo con la chiamata .toLowerCase(). Nomi come "McDonald" o acronimi come "ASAP" devono conservare i caratteri maiuscoli. Se qualcuno ha effettivamente passato una stringa come "heLLO", l'applicazione non dovrebbe presumere che le lettere maiuscole siano errate.
Thomas Higginbotham,

1
@ThomasHigginbotham Che ne dici di questo? String.prototype.toTitleCase = function (blnForceLower) { var strReturn; (blnForceLower ? strReturn = this.toLowerCase() : strReturn = this); return strReturn .split(' ') .map(i => i[0].toUpperCase() + i.substr(1)) .join(' '); }
Sean Kendle,

Sì, sarebbe preferibile fornire un'opzione per forzare le lettere minuscole.
Thomas Higginbotham,

1
Questo si interromperà se strè un singolo personaggio.
Madbreaks,

103

Ecco la mia funzione che converte in maiuscolo, ma conserva anche gli acronimi definiti in maiuscolo e in minuscolo:

String.prototype.toTitleCase = function() {
  var i, j, str, lowers, uppers;
  str = this.replace(/([^\W_]+[^\s-]*) */g, function(txt) {
    return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
  });

  // Certain minor words should be left lowercase unless 
  // they are the first or last words in the string
  lowers = ['A', 'An', 'The', 'And', 'But', 'Or', 'For', 'Nor', 'As', 'At', 
  'By', 'For', 'From', 'In', 'Into', 'Near', 'Of', 'On', 'Onto', 'To', 'With'];
  for (i = 0, j = lowers.length; i < j; i++)
    str = str.replace(new RegExp('\\s' + lowers[i] + '\\s', 'g'), 
      function(txt) {
        return txt.toLowerCase();
      });

  // Certain words such as initialisms or acronyms should be left uppercase
  uppers = ['Id', 'Tv'];
  for (i = 0, j = uppers.length; i < j; i++)
    str = str.replace(new RegExp('\\b' + uppers[i] + '\\b', 'g'), 
      uppers[i].toUpperCase());

  return str;
}

Per esempio:

"TO LOGIN TO THIS SITE and watch tv, please enter a valid id:".toTitleCase();
// Returns: "To Login to This Site and Watch TV, Please Enter a Valid ID:"

1
Mi è piaciuto il tuo, ho riscontrato anche problemi quando ho a che fare con numeri romani ... ho appena corretto con I, II, III, IV, ecc.
Marcelo,

2
Fisso. La regex nella terza riga è stato cambiato da /\w\S*/ga /([^\W_]+[^\s-]*) */gper @ di awashburn commento di cui sopra per affrontare questo.
Geoffrey Booth

2
C'è un vantaggio da guadagnare usando il tuo modello regex /\b\w+/g, che trovo più rapidamente comprensibile?
Michael - Dov'è Clay Shirky

2
Non che io possa vedere, stavo semplicemente prendendo il suggerimento di un altro commentatore per risolvere il problema delle parole sillabate; ma la tua regex sembra fare altrettanto bene e la semplicità è sempre migliore. Per i posteri e i futuri visitatori di questo post, ho appena cambiato la regex nella terza riga da /([^\W_]+[^\s-]*) */gal /\b\w+/gcommento di @ Michael; commenta se trovi un caso in cui è necessaria la regex più complicata.
Geoffrey Booth,

1
Ho cambiato la regex di terza riga /\b[\w-\']+/gin per consentire parole sillabate e apostrofo in parole.
Shamasis Bhattacharya,

47

Preferisco quanto segue alle altre risposte. Corrisponde solo alla prima lettera di ogni parola e la mette in maiuscolo. Codice più semplice, più facile da leggere e meno byte. Conserva le lettere maiuscole esistenti per evitare distorsioni degli acronimi. Tuttavia, puoi sempre chiamare toLowerCase()prima la tua stringa.

function title(str) {
  return str.replace(/(^|\s)\S/g, function(t) { return t.toUpperCase() });
}

Puoi aggiungere questo al tuo prototipo di stringa che ti permetterà di 'my string'.toTitle():

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

Esempio:


3
È ancora più bello come un lambdaconst titleCase = (str) => str.replace(/\b\S/g, t => t.toUpperCase());
0xcaff

Non volevo interrompere IE, ma sì, se l'applicazione non è sensibile al browser legacy potrebbe essere più breve.
Tom Kay,

Questa è solo una soluzione parziale - op ha chiesto come convertire una stringa in maiuscolo / minuscolo. Questa risposta non lo raggiunge per input come NoT qUiITe.
Madbreaks,

@Madbreaks La domanda non prevedeva la conversione di input di casi misti. Tuttavia, ho aggiornato la risposta menzionando toLowerCase. Basta essere consapevoli del fatto che romperebbe gli acronimi. an HTML document: An HTML DocumentvsAn Html Document
Tom Kay,

4
@Madbreaks Mentre il tuo esempio iniziale è stato inventato, fai un buon punto affermando che l'output sarebbe invariato se l'input fosse capitalizzato. Detto questo, ritengo che la risposta così com'è (con la modifica suggerita toLowerCase) sia più flessibile / utile di quella che assume le intenzioni degli sviluppatori. Questo metodo riflette anche la funzionalità di metodi incorporati simili di altre lingue come PHP ( ucwords) e Golang ( strings.Title). .NET ( TextInfo.ToTitleCase) funziona in modo interessante con maiuscole e minuscole, ma lascia invariate anche le stringhe completamente in maiuscolo.
Tom Kay,

20

Senza usare regex solo come riferimento:

String.prototype.toProperCase = function() {
  var words = this.split(' ');
  var results = [];
  for (var i = 0; i < words.length; i++) {
    var letter = words[i].charAt(0).toUpperCase();
    results.push(letter + words[i].slice(1));
  }
  return results.join(' ');
};

console.log(
  'john smith'.toProperCase()
)


Grazie per la soluzione gratuita regex!
lucifer63,

20

var result =
  'this is very interesting'.replace(/\b[a-z]/g, (x) => x.toUpperCase())

console.log(result) // This Is Very Interesting


Solo una domanda, il costrutto () serve per specificare una corrispondenza su una qualsiasi di una sequenza di opzioni: ovvero, (a | b) corrisponde a a o b. Cosa fa la costruzione (.)?
Michael Blackburn,

Per chiunque abbia avuto la stessa domanda, definisce un "BLOB" sostitutivo che viene utilizzato nella sezione di sostituzione. I BLOB sono numerati in sequenza, il primo () viene messo in $ 1, il secondo in $ 2. Ho trovato utile questo sito: javascript.info/tutorial/regular-expressions-methods
Michael Blackburn il

Non riesco a far funzionare quanto sopra, ma sono tutt'altro che un mago regex. Sto usando 'string'.replace(/^(.)(.*)/,function(s,p1,p2){return p1.toUpperCase()+p2;}) Again, questo funziona solo per scrivere in maiuscolo la prima lettera di una stringa, ma nel caso sia quello che ti serve, la mia costruzione funziona.
Michael Blackburn,

1
Per qualche motivo FF35 sembra soffocare '$1'.toUpperCase(), sembra che la maiuscola non sia stata eseguita al momento dell'assegnazione del valore. È stato 'string'.replace(/^(.){1}/,function(match) { return match.toUpperCase(); })
risolto il problema

Ciao a tutti, la risposta è fissa! Sono abbastanza sicuro che funzionasse quando l'ho pubblicato inizialmente. Comunque grazie per l'input!
simo

17

È possibile immediatamente toLowerCasela stringa e quindi solo toUpperCasela prima lettera di ogni parola. Diventa un semplice 1 liner:

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

console.log(titleCase('iron man'));
console.log(titleCase('iNcrEdible hulK'));


Mi piace questa soluzione; bello e semplice. Sembra che un po 'di CoffeeScript sia scivolato nella tua risposta ( s => s.toUpperCase()). La mia variante è fare quello che hai fatto, ma estendere l'oggetto String (per quanto controverso sia):Object.defineProperty(String.prototype, '_toProperCase', {value:function() {return this.toLowerCase().replace(/\b(\w)/g, function(t) {return t.toUpperCase()})}})
Waz

1
@Waz, grazie per le idee! Volevo solo chiarire =>che, ovvero una funzione di freccia nativa (ES6), il collegamento salta ai documenti Mozillla su di essi che fornisce anche una tabella di supporto.
KevBot

16

Nel caso in cui tu sia preoccupato per quelle parole di riempimento, puoi sempre dire alla funzione cosa non capitalizzare.

/**
 * @param String str The text to be converted to titleCase.
 * @param Array glue the words to leave in lowercase. 
 */
var titleCase = function(str, glue){
    glue = (glue) ? glue : ['of', 'for', 'and'];
    return str.replace(/(\w)(\w*)/g, function(_, i, r){
        var j = i.toUpperCase() + (r != null ? r : "");
        return (glue.indexOf(j.toLowerCase())<0)?j:j.toLowerCase();
    });
};

Spero che questo ti aiuti.

modificare

Se vuoi gestire le parole di colla principali, puoi tenere traccia di questa w / un'altra variabile:

var titleCase = function(str, glue){
    glue = !!glue ? glue : ['of', 'for', 'and', 'a'];
    var first = true;
    return str.replace(/(\w)(\w*)/g, function(_, i, r) {
        var j = i.toUpperCase() + (r != null ? r : '').toLowerCase();
        var result = ((glue.indexOf(j.toLowerCase()) < 0) || first) ? j : j.toLowerCase();
        first = false;
        return result;
    });
};

2
È possibile esplodere una stringa in un array. Quindi potremmo avere preposizioni portoghesi, spagnole, italiane e francesi:glue ='de|da|del|dos|do|das|des|la|della|delli'.split('|');
Junior Mayhé,

Ciò non garantirà la maiuscola della prima parola; cioè and another thingdiventa and Another Thing. Ho solo bisogno di un modo elegante per capitalizzare sempre la prima parola.
Brad Koch,

@BradKoch - pad con spazi in modo da utilizzare 'e', ​​'de', ecc. Come parola di ricerca, quindi 'And Another And Another' sostituirà 'And Another and Another'.
Yimin Rong

buono tranne che maiuscole anche dopo 'e - come H'Dy o Number-One
luky

Invece di usare un operatore ternario potresti semplicemente usare un fallback: colla = colla || ['of', 'for', 'and', 'a'];
tm2josep,

14

Se regex utilizzato nelle soluzioni sopra ti fa confondere, prova questo codice:

function titleCase(str) {
  return str.split(' ').map(function(val){ 
    return val.charAt(0).toUpperCase() + val.substr(1).toLowerCase();
  }).join(' ');
}

lo adoro! nessuna conversione in array.
Neelmeg,

1
uhhh ... split lo converte in un array, semplicemente non lo vedi come ovviamente perché mapsignifica che non devi usare la []notazione
MalcolmOcean


1
Interruzioni per input a carattere singolo.
Madbreaks,

1
@AlexChaffee controlla la cronologia delle revisioni. a8m non ha utilizzato una funzione freccia nella risposta originale.
Grazie

9

Ho creato questa funzione che può gestire i cognomi (quindi non è il caso del titolo) come "McDonald" o "MacDonald" o "O'Toole" o "D'Orazio". Tuttavia non gestisce i nomi tedeschi o olandesi con "van" o "von" che sono spesso in minuscolo ... Credo che "de" sia spesso anche in minuscolo come "Robert de Niro". Questi dovrebbero ancora essere affrontati.

function toProperCase(s)
{
  return s.toLowerCase().replace( /\b((m)(a?c))?(\w)/g,
          function($1, $2, $3, $4, $5) { if($2){return $3.toUpperCase()+$4+$5.toUpperCase();} return $1.toUpperCase(); });
}

1
+1 per la consapevolezza del nome. Tuttavia, non gestisce correttamente "macy".
brianary,

Questa è stata l'unica funzione che ha gestito correttamente la trasformazione di maiuscole e minuscole nel caso corretto e che ha notato iniziali come "Isole Vergini americane".
Rodrigo Polo,

Puoi aggirare il macyproblema mettendo uno sguardo negativo lì dentro così \b((m)(a?c))?(\w)diventa\b((m)(a?c))?(\w)(?!\s)
Ste

8
var toMatch = "john w. smith";
var result = toMatch.replace(/(\w)(\w*)/g, function (_, i, r) {
      return i.toUpperCase() + (r != null ? r : "");
    }
)

Sembra funzionare ... Testato con quanto sopra, "the quick-brown, fox? / Jumps / ^ over ^ the ¡lazy! Dog ..." e "C: / programmi / alcuni venditori / la loro seconda applicazione / a file1.txt".

Se si desidera il 2o invece del 2o, è possibile passare a /([a-z])(\w*)/g .

Il primo modulo può essere semplificato come:

function toTitleCase(toTransform) {
  return toTransform.replace(/\b([a-z])/g, function (_, initial) {
      return initial.toUpperCase();
  });
}

7

Prova questo

String.prototype.toProperCase = function(){
    return this.toLowerCase().replace(/(^[a-z]| [a-z]|-[a-z])/g, 
        function($1){
            return $1.toUpperCase();
        }
    );
};

Esempio

var str = 'john smith';
str.toProperCase();

7

Se puoi usare librerie di terze parti nel tuo codice, lodash ha una funzione di supporto per noi.

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'


7

Prova questo, il modo più breve:

str.replace(/(^[a-z])|(\s+[a-z])/g, txt => txt.toUpperCase());

7

ES 6

str.split(' ')
   .map(s => s.slice(0, 1).toUpperCase() + s.slice(1).toLowerCase())
   .join(' ')

altro

str.split(' ').map(function (s) {
    return s.slice(0, 1).toUpperCase() + s.slice(1).toLowerCase();
}).join(' ')

Solo un avvertimento, probabilmente dovrebbe essere s.slice(0, 1).toUpperCase()se vuoi ancora quella prima lettera.
WindsofTime

@jssridhar dovresti anche correggere il codice in ES6.
caiosm1005,

1
Rompe se strè un singolo personaggio
Madbreaks,

@jssridhar potrebbe essere migliore per noi .charAt(0).toUpperCase().
roydukkey,

2
duplicato della risposta di a8m
Grazie

6

La maggior parte di queste risposte sembra ignorare la possibilità di usare la parola confine metacarattere (\ b). Una versione più breve della risposta di Greg Dean che la utilizza:

function toTitleCase(str)
{
    return str.replace(/\b\w/g, function (txt) { return txt.toUpperCase(); });
}

Funziona anche con nomi sillabati come Jim-Bob.


2
È un'elegante soluzione parziale ma non funziona con accenti o stringhe maiuscole. Ottengo "Sofía Vergara" => "SofíA Vergara" o "Sofía VERGARA" => "SofíA VERGARA". Il secondo caso potrebbe essere risolto con la funzione apply .toLowerCase () prima di .replace (...). Il primo caso deve trovare una giusta espressione regolare.
Asereware,

2
Hmm, sembra un bug nell'implementazione di regex, penso che i caratteri accentati dovrebbero essere caratteri di parole (hai ragione però, dato che non funziona per quei casi).
lewax00,

\winclude solo i personaggi [A-Za-z0-9_], non tutte le lettere. Per questo dovresti usare la categoria Unicode \p{L}. Avrai bisogno del /umodificatore (vedi qui ) e di una soluzione diversa per \b, che funziona solo tra \We \w(vedi qui )
cmbuckley

6

Penso che il più semplice stia usando il CSS.

function format_str(str) {
    str = str.toLowerCase();
    return '<span style="text-transform: capitalize">'+ str +'</span>';
}

Ho aggiornato il codice e testato. Dovrebbe funzionare ora.
Wondim

Puoi usare CSS in una frazione degli ambienti in cui viene utilizzato JS, quindi questa soluzione non è praticabile. Anche gli stili in linea dovrebbero essere evitati a tutti i costi.
Madbreaks,

5

Utilizzare /\S+/gper supportare i segni diacritici:

function toTitleCase(str) {
  return str.replace(/\S+/g, str => str.charAt(0).toUpperCase() + str.substr(1).toLowerCase());
}

console.log(toTitleCase("a city named örebro")); // A City Named Örebro

Tuttavia: " s unshine ( y ellow )" ⇒ " S unshine ( y ellow )"


5

Volevo aggiungere la mia risposta poiché avevo bisogno di una solida toTitleCasefunzione che tenga conto delle regole grammaticali elencate qui (articolo consigliato da Google). Esistono varie regole che dipendono dalla lunghezza della stringa di input. Di seguito è la funzione + test unitari.

La funzione consolida anche gli spazi bianchi e rimuove i caratteri speciali (modifica regex per le tue esigenze)

Funzione toTitleCase

const toTitleCase = (str) => {
  const articles = ['a', 'an', 'the'];
  const conjunctions = ['for', 'and', 'nor', 'but', 'or', 'yet', 'so'];
  const prepositions = [
    'with', 'at', 'from', 'into','upon', 'of', 'to', 'in', 'for',
    'on', 'by', 'like', 'over', 'plus', 'but', 'up', 'down', 'off', 'near'
  ];

  // The list of spacial characters can be tweaked here
  const replaceCharsWithSpace = (str) => str.replace(/[^0-9a-z&/\\]/gi, ' ').replace(/(\s\s+)/gi, ' ');
  const capitalizeFirstLetter = (str) => str.charAt(0).toUpperCase() + str.substr(1);
  const normalizeStr = (str) => str.toLowerCase().trim();
  const shouldCapitalize = (word, fullWordList, posWithinStr) => {
    if ((posWithinStr == 0) || (posWithinStr == fullWordList.length - 1)) {
      return true;
    }

    return !(articles.includes(word) || conjunctions.includes(word) || prepositions.includes(word));
  }

  str = replaceCharsWithSpace(str);
  str = normalizeStr(str);

  let words = str.split(' ');
  if (words.length <= 2) { // Strings less than 3 words long should always have first words capitalized
    words = words.map(w => capitalizeFirstLetter(w));
  }
  else {
    for (let i = 0; i < words.length; i++) {
      words[i] = (shouldCapitalize(words[i], words, i) ? capitalizeFirstLetter(words[i], words, i) : words[i]);
    }
  }

  return words.join(' ');
}

Test unitari per garantire la correttezza

import { expect } from 'chai';
import { toTitleCase } from '../../src/lib/stringHelper';

describe('toTitleCase', () => {
  it('Capitalizes first letter of each word irrespective of articles, conjunctions or prepositions if string is no greater than two words long', function(){
    expect(toTitleCase('the dog')).to.equal('The Dog'); // Capitalize articles when only two words long
    expect(toTitleCase('for all')).to.equal('For All'); // Capitalize conjunctions when only two words long
    expect(toTitleCase('with cats')).to.equal('With Cats'); // Capitalize prepositions when only two words long
  });

  it('Always capitalize first and last words in a string irrespective of articles, conjunctions or prepositions', function(){
    expect(toTitleCase('the beautiful dog')).to.equal('The Beautiful Dog');
    expect(toTitleCase('for all the deadly ninjas, be it so')).to.equal('For All the Deadly Ninjas Be It So');
    expect(toTitleCase('with cats and dogs we are near')).to.equal('With Cats and Dogs We Are Near');
  });

  it('Replace special characters with space', function(){
    expect(toTitleCase('[wolves & lions]: be careful')).to.equal('Wolves & Lions Be Careful');
    expect(toTitleCase('wolves & lions, be careful')).to.equal('Wolves & Lions Be Careful');
  });

  it('Trim whitespace at beginning and end', function(){
    expect(toTitleCase(' mario & Luigi superstar saga ')).to.equal('Mario & Luigi Superstar Saga');
  });

  it('articles, conjunctions and prepositions should not be capitalized in strings of 3+ words', function(){
    expect(toTitleCase('The wolf and the lion: a tale of two like animals')).to.equal('The Wolf and the Lion a Tale of Two like Animals');
    expect(toTitleCase('the  three Musketeers  And plus ')).to.equal('The Three Musketeers and Plus');
  });
});

Si noti che sto rimuovendo un bel po 'di caratteri speciali dalle stringhe fornite. Dovrai modificare la regex per soddisfare i requisiti del tuo progetto.


Preferisco questa soluzione poiché si occupa davvero del caso del titolo. Non è "Via col vento" è "Via col vento"
russellmania,

5
"john f. kennedy".replace(/\b\S/g, t => t.toUpperCase())

1
Funziona per il campione e o'henry, ma fa cose strane con horse's mouth.
Michael - Dov'è Clay Shirky il

"john f. kennEdy".toLowerCase().replace(/\b\S/g, t => t.toUpperCase())meglio 🤔
w3debugger

Non volevo modificare la risposta di @ Proximo: le \be \Ssono classi di caratteri speciali che indicano "confine di parole" e "carattere singolo, non di spazi bianchi. Quindi, la regex corrisponde a ogni singolo carattere che segue un limite di parole e capitalizza quel carattere applicando la funzione freccia indicata.
Jens,

4

Prendendo la soluzione "lewax00" ho creato questa semplice soluzione che costringe a "w" a partire dallo spazio o "w" che avvia de word, ma non è in grado di rimuovere gli spazi intermedi extra.

"SOFÍA vergara".toLowerCase().replace(/\b(\s\w|^\w)/g, function (txt) { return txt.toUpperCase(); });

Il risultato è "Sofia Vergara".


4

Ecco la mia funzione che si occupa dei caratteri accentati (importante per il francese!) E che può attivare / disattivare la gestione delle eccezioni più basse. Spero che aiuti.

String.prototype.titlecase = function(lang, withLowers = false) {
    var i, string, lowers, uppers;

    string = this.replace(/([^\s:\-'])([^\s:\-']*)/g, function(txt) {
        return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
    }).replace(/Mc(.)/g, function(match, next) {
        return 'Mc' + next.toUpperCase();
    });

    if (withLowers) {
        if (lang == 'EN') {
            lowers = ['A', 'An', 'The', 'At', 'By', 'For', 'In', 'Of', 'On', 'To', 'Up', 'And', 'As', 'But', 'Or', 'Nor', 'Not'];
        }
        else {
            lowers = ['Un', 'Une', 'Le', 'La', 'Les', 'Du', 'De', 'Des', 'À', 'Au', 'Aux', 'Par', 'Pour', 'Dans', 'Sur', 'Et', 'Comme', 'Mais', 'Ou', 'Où', 'Ne', 'Ni', 'Pas'];
        }
        for (i = 0; i < lowers.length; i++) {
            string = string.replace(new RegExp('\\s' + lowers[i] + '\\s', 'g'), function(txt) {
                return txt.toLowerCase();
            });
        }
    }

    uppers = ['Id', 'R&d'];
    for (i = 0; i < uppers.length; i++) {
        string = string.replace(new RegExp('\\b' + uppers[i] + '\\b', 'g'), uppers[i].toUpperCase());
    }

    return string;
}

4

Abbiamo discusso qui in ufficio e pensiamo che cercare di correggere automaticamente il modo in cui le persone inseriscono i nomi nel modo in cui lo desideri sia pieno di possibili problemi.

Abbiamo escogitato diversi casi in cui i diversi tipi di capitalizzazione automatica cadono a pezzi e questi sono solo per i nomi inglesi, ogni lingua ha le sue complessità.

Problemi con la maiuscola della prima lettera di ciascun nome:

• Acronimi come IBM non possono essere immessi, si trasformerebbero in Ibm.

• Il nome McDonald si trasformerebbe in Mcdonald che non è corretto, la stessa cosa è anche MacDonald.

• I nomi a doppia canna come Marie-Tonks verrebbero trasformati in Marie-tonks.

• Nomi come O'Connor si trasformerebbero in O'connor.

Per la maggior parte di questi potresti scrivere regole personalizzate per affrontarlo, tuttavia, questo ha ancora problemi con gli acronimi come prima e ottieni un nuovo problema:

• Aggiungendo una regola per correggere i nomi con Mac come MacDonald, i nomi delle interruzioni come Macy potrebbero trasformarlo in MacY.

L'unica soluzione che abbiamo trovato che non è mai errata è quella di capitalizzare ogni lettera che è un metodo di forza bruta che la DBS sembra usare anche.

Quindi, se vuoi automatizzare il processo, è altrettanto impossibile fare a meno di un dizionario di ogni singolo nome e parola e come dovrebbe essere in maiuscolo, se non hai una regola che copre tutto, non usarlo come infastidirà i tuoi utenti e chiederà alle persone che vogliono inserire correttamente i loro nomi di andare altrove.


4

ecco un'altra soluzione che usa css (e javascript, se il testo che vuoi trasformare è in maiuscolo):

html

<span id='text'>JOHN SMITH</span>

js

var str = document.getElementById('text').innerHtml;
var return_text = str.toLowerCase();

css

#text{text-transform:capitalize;}

3

Per quelli di noi che hanno paura delle espressioni regolari (lol):

function titleCase(str)
{
    var words = str.split(" ");
    for ( var i = 0; i < words.length; i++ )
    {
        var j = words[i].charAt(0).toUpperCase();
        words[i] = j + words[i].substr(1);
    }
    return words.join(" ");
}


3

La mia soluzione a una linea:

String.prototype.capitalizeWords = function() {
    return this.split(" ").map(function(ele){ return ele[0].toUpperCase() + ele.slice(1).toLowerCase();}).join(" ");
};

Quindi, puoi chiamare il metodo capitalizeWords()su qualsiasi stringa. Per esempio:

var myS = "this actually works!";
myS.capitalizeWords();

>>> This Actually Works

La mia altra soluzione:

function capitalizeFirstLetter(word) {
    return word[0].toUpperCase() + word.slice(1).toLowerCase();
}
String.prototype.capitalizeAllWords = function() {
    var arr = this.split(" ");
    for(var i = 0; i < arr.length; i++) {
        arr[i] = capitalizeFirstLetter(arr[i]);
    }
    return arr.join(" ");
};

Quindi, puoi chiamare il metodo capitalizeWords()su qualsiasi stringa. Per esempio:

var myStr = "this one works too!";
myStr.capitalizeWords();

>>> This One Works Too

Soluzione alternativa basata sulla risposta di Greg Dean:

function capitalizeFirstLetter(word) {
    return word[0].toUpperCase() + word.slice(1).toLowerCase();
}
String.prototype.capitalizeWords = function() {
    return this.replace(/\w\S*/g, capitalizeFirstLetter);
};

Quindi, puoi chiamare il metodo capitalizeWords()su qualsiasi stringa. Per esempio:

var myString = "yes and no";
myString.capitalizeWords()

>>> Yes And No

3

Sorpreso di non vedere nessuno menzionato l'uso del parametro rest. Ecco una semplice fodera che utilizza i parametri di riposo ES6.

let str="john smith"
str=str.split(" ").map(([firstChar,...rest])=>firstChar.toUpperCase()+rest.join("").toLowerCase()).join(" ")
console.log(str)


2

Questo si basa sulla mia soluzione per "Title Case" del falò di FreeCodeCamp , che richiede prima di convertire la stringa data in tutte le lettere minuscole e poi di convertire tutti i caratteri procedendo uno spazio in lettere maiuscole.

Senza usare regex:

function titleCase(str) {
 return str.toLowerCase().split(' ').map(function(val) { return val.replace(val[0], val[0].toUpperCase()); }).join(' ');
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.