Esiste un modo semplice per convertire una stringa in case del titolo? Ad esempio john smith
diventa John Smith
. Non sto cercando qualcosa di complicato come la soluzione di John Resig , solo (si spera) una specie di una o due linee.
Esiste un modo semplice per convertire una stringa in case del titolo? Ad esempio john smith
diventa John Smith
. Non sto cercando qualcosa di complicato come la soluzione di John Resig , solo (si spera) una specie di una o due linee.
Risposte:
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>
\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 .
\w\S*
anche causato il Jim-bob
problema da parte nostra. Usando \w*
risolto questo.
/([^\W_]+[^\s-]*) */g
risolve il Jim-Bob
problema, ovvero:jim-bob
-->
Jim-Bob
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();});
\w\S*
viene utilizzato al posto \w+
o meno in \w*
modo che parole come Don't
non vengano modificate Don'T
, ma come altri hanno sottolineato \w\S*
causa problemi con parole sillabate.
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();
Jo-Ann Smith
, questo codice convertirli Jo-ann Smith
(notare il minuscolo a
in Ann
).
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.
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"
str.split(' ').map(i => i[0].toUpperCase() + i.substring(1).toLowerCase()).join(' ')
.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.
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(' '); }
str
è un singolo personaggio.
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:"
/\w\S*/g
a /([^\W_]+[^\s-]*) */g
per @ di awashburn commento di cui sopra per affrontare questo.
/\b\w+/g
, che trovo più rapidamente comprensibile?
/([^\W_]+[^\s-]*) */g
al /\b\w+/g
commento di @ Michael; commenta se trovi un caso in cui è necessaria la regex più complicata.
/\b[\w-\']+/g
in per consentire parole sillabate e apostrofo in parole.
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:
const titleCase = (str) => str.replace(/\b\S/g, t => t.toUpperCase());
NoT qUiITe
.
toLowerCase
. Basta essere consapevoli del fatto che romperebbe gli acronimi. an HTML document
: An HTML Document
vsAn Html Document
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.
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()
)
var result =
'this is very interesting'.replace(/\b[a-z]/g, (x) => x.toUpperCase())
console.log(result) // This Is Very Interesting
'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.
'$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(); })
È possibile immediatamente toLowerCase
la stringa e quindi solo toUpperCase
la 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'));
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()})}})
=>
che, ovvero una funzione di freccia nativa (ES6), il collegamento salta ai documenti Mozillla su di essi che fornisce anche una tabella di supporto.
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.
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;
});
};
glue ='de|da|del|dos|do|das|des|la|della|delli'.split('|');
and another thing
diventa and Another Thing
. Ho solo bisogno di un modo elegante per capitalizzare sempre la prima parola.
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(' ');
}
split
lo converte in un array, semplicemente non lo vedi come ovviamente perché map
significa che non devi usare la []
notazione
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(); });
}
macy
problema mettendo uno sguardo negativo lì dentro così \b((m)(a?c))?(\w)
diventa\b((m)(a?c))?(\w)(?!\s)
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();
});
}
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'
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(' ')
s.slice(0, 1).toUpperCase()
se vuoi ancora quella prima lettera.
str
è un singolo personaggio
.charAt(0).toUpperCase()
.
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.
Penso che il più semplice stia usando il CSS.
function format_str(str) {
str = str.toLowerCase();
return '<span style="text-transform: capitalize">'+ str +'</span>';
}
Utilizzare /\S+/g
per 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 )"
Volevo aggiungere la mia risposta poiché avevo bisogno di una solida toTitleCase
funzione 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.
"john f. kennedy".replace(/\b\S/g, t => t.toUpperCase())
o'henry
, ma fa cose strane con horse's mouth
.
"john f. kennEdy".toLowerCase().replace(/\b\S/g, t => t.toUpperCase())
meglio 🤔
\b
e \S
sono 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.
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".
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;
}
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.
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(" ");
}
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
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)
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(' ');
}