Czy istnieje prosty sposób konwersji ciągu na wielkość liter? Na przykładjohn smith
John Smith
. Staje się . Nie szukam czegoś skomplikowanego jak rozwiązanie Johna Resiga , tylko (mam nadzieję) jakiś jedno- lub dwuwarstwowy .
Czy istnieje prosty sposób konwersji ciągu na wielkość liter? Na przykładjohn smith
John Smith
. Staje się . Nie szukam czegoś skomplikowanego jak rozwiązanie Johna Resiga , tylko (mam nadzieję) jakiś jedno- lub dwuwarstwowy .
Odpowiedzi:
Spróbuj tego:
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*
jest używany zamiast \w+
lub \w*
na przykład? Nie wiem, dlaczego chcesz wstawić tylko spacje i dlatego zmienić Jim-Bob na Jim-bob .
\w\S*
również spowodował Jim-bob
problem z naszej strony. Korzystanie \w*
rozwiązało to.
/([^\W_]+[^\s-]*) */g
rozwiązuje Jim-Bob
problem, tj .:jim-bob
-->
Jim-Bob
jim-bob
-->
Jim-Bob
jest twoje pragnienie, prawdopodobnie powinieneś to zrobić /\b\w+/g
. Przykład:str.replace(/\b\w+/g,function(s){return s.charAt(0).toUpperCase() + s.substr(1).toLowerCase();});
\w\S*
jest używane zamiast \w+
lub w \w*
taki sposób, że słowa takie Don't
nie są modyfikowane Don'T
, ale jak zauważyli inni, \w\S*
powodują problemy ze słowami dzielonymi.
Nieco bardziej elegancki sposób, dostosowujący funkcję Grega Deana:
String.prototype.toProperCase = function () {
return this.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();});
};
Nazwij to tak:
"pascal".toProperCase();
Jo-Ann Smith
ten kod będzie przekonwertować je na Jo-ann Smith
(uwaga na małe litery a
w Ann
).
Spróbuj zastosować styl CSS z transformacją tekstu do swoich kontrolek.
na przykład: (text-transform: capitalize);
Stosuj podejście JS tylko wtedy, gdy jest to absolutnie konieczne.
Oto moja wersja, IMO jest łatwa do zrozumienia i elegancka.
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()
. Nazwy takie jak „McDonald” lub akronimy takie jak „ASAP” powinny zachować swoje wielkie litery. Jeśli ktoś faktycznie przekazał ciąg taki jak „heLLO”, aplikacja nie powinna zakładać, że wielkie litery są niepoprawne.
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
jest to jedna postać.
Oto moja funkcja, która konwertuje na wielkość liter, ale zachowuje również zdefiniowane akronimy jako wielkie litery, a małe słowa jako małe:
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;
}
Na przykład:
"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
na /([^\W_]+[^\s-]*) */g
na komentarz powyżej @ awashburn, aby rozwiązać ten problem.
/\b\w+/g
, jaką można uzyskać, stosując wzorzec wyrażenia regularnego , który wydaje mi się szybszy do zrozumienia?
/([^\W_]+[^\s-]*) */g
na /\b\w+/g
na komentarz per @ Michael; prosimy o komentarz, jeśli znajdziesz przypadek, w którym konieczne jest zastosowanie bardziej skomplikowanego wyrażenia regularnego.
/\b[\w-\']+/g
, aby umożliwić łączenie wyrazów i apostrof w słowach.
Wolę poniższe niż inne odpowiedzi. Dopasowuje tylko pierwszą literę każdego słowa i dodaje wielkie litery. Prostszy kod, łatwiejszy do odczytania i mniej bajtów. Zachowuje istniejące duże litery, aby zapobiec zniekształcaniu akronimów. Jednak zawsze możesz najpierw wywołać toLowerCase()
swój ciąg.
function title(str) {
return str.replace(/(^|\s)\S/g, function(t) { return t.toUpperCase() });
}
Możesz dodać to do swojego prototypu ciągu, co pozwoli ci 'my string'.toTitle()
w następujący sposób:
String.prototype.toTitle = function() {
return this.replace(/(^|\s)\S/g, function(t) { return t.toUpperCase() });
}
Przykład:
const titleCase = (str) => str.replace(/\b\S/g, t => t.toUpperCase());
NoT qUiITe
.
toLowerCase
. Pamiętaj tylko, że złamałoby to akronimy. an HTML document
: An HTML Document
vsAn Html Document
toLowerCase
) jest bardziej elastyczna / użyteczna niż ta, która zakłada intencje programistów. Ta metoda odzwierciedla również funkcjonalność podobnych wbudowanych metod innych języków, takich jak PHP ( ucwords
) i Golang ( strings.Title
). .NET ( TextInfo.ToTitleCase
) ciekawie działa w przypadku małych i wielkich liter, ale pozostawiłby również w pełni niezmienione wielkie litery.
Bez użycia wyrażenia regularnego wyłącznie w celach informacyjnych:
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;})
Znowu, to działa tylko na wielkie litery pierwszej litery, ale w przypadku, gdy tego potrzebujesz, moja konstrukcja działa.
'$1'.toUpperCase()
, wydaje się, że wielkie litery nie zostały wykonane przed przypisaniem wartości. 'string'.replace(/^(.){1}/,function(match) { return match.toUpperCase(); })
Możesz od razu toLowerCase
ciąg, a następnie tylko toUpperCase
pierwszą literę każdego słowa. Staje się bardzo prostym 1 linijką:
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()
). Moim wariantem jest robienie tego, co zrobiłeś, ale rozszerzanie obiektu String (jakkolwiek kontrowersyjnego):Object.defineProperty(String.prototype, '_toProperCase', {value:function() {return this.toLowerCase().replace(/\b(\w)/g, function(t) {return t.toUpperCase()})}})
=>
polega natywna funkcja strzałki (ES6), link przeskakuje do nich w Dokumentach Mozillla, które również zapewniają tabelę wsparcia.
Na wszelki wypadek, gdy martwisz się wypełniającymi słowami, zawsze możesz po prostu powiedzieć tej funkcji, czego nie należy pisać dużymi literami.
/**
* @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();
});
};
Mam nadzieję, że to ci pomoże.
Jeśli chcesz obsługiwać wiodące słowa kleju, możesz śledzić tę w / jeszcze jedną zmienną:
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
staje się and Another Thing
. Potrzebujesz tylko eleganckiego sposobu, aby zawsze używać pierwszego słowa.
Jeśli regex użyty w powyższych rozwiązaniach powoduje dezorientację, wypróbuj ten kod:
function titleCase(str) {
return str.split(' ').map(function(val){
return val.charAt(0).toUpperCase() + val.substr(1).toLowerCase();
}).join(' ');
}
split
ma przekształcić go do tablicy, po prostu nie widzę go jako oczywisty, ponieważ map
oznacza, że nie trzeba używać []
notacji
Stworzyłem tę funkcję, która może obsługiwać nazwiska (więc nie jest to przypadek tytułu), takie jak „McDonald” lub „MacDonald” lub „O'Toole” lub „D'Orazio”. Nie obsługuje jednak niemieckich ani holenderskich nazw z „van” lub „von”, które są często pisane małymi literami ... Wierzę, że „de” jest często małymi literami, np. „Robert de Niro”. Trzeba je jeszcze rozwiązać.
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
problem, umieszczając w nim negatywne spojrzenie, tak więc \b((m)(a?c))?(\w)
staje się\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 : "");
}
)
Wydaje się, że działa ... Testowany z powyższym, „szybkobrązowy, lis? / Skacze / ^ ponad ^ leniwy! Pies ...” i „C: / pliki programów / jakiś dostawca / ich 2. aplikacja / a plik1.txt ”.
Jeśli chcesz 2Nd zamiast 2, możesz zmienić na /([a-z])(\w*)/g
.
Pierwszy formularz można uprościć jako:
function toTitleCase(toTransform) {
return toTransform.replace(/\b([a-z])/g, function (_, initial) {
return initial.toUpperCase();
});
}
Jeśli możesz używać bibliotek stron trzecich w swoim kodzie, lodash ma dla nas funkcję pomocniczą.
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(' ')
jeszcze
str.split(' ').map(function (s) {
return s.slice(0, 1).toUpperCase() + s.slice(1).toLowerCase();
}).join(' ')
s.slice(0, 1).toUpperCase()
jeśli nadal chcesz ten pierwszy list.
str
.charAt(0).toUpperCase()
.
Większość z tych odpowiedzi wydaje się ignorować możliwość użycia słowa metaznak granicy (\ b). Krótsza wersja wykorzystującej ją odpowiedzi Grega Deana:
function toTitleCase(str)
{
return str.replace(/\b\w/g, function (txt) { return txt.toUpperCase(); });
}
Działa z nazwami dzielonymi, takimi jak Jim-Bob.
\w
zawiera tylko znaki [A-Za-z0-9_]
, a nie wszystkie litery. W tym celu musisz użyć kategorii Unicode \p{L}
. Będziesz potrzebował /u
modyfikatora (patrz tutaj ) i innego rozwiązania dla \b
, które działa tylko pomiędzy \W
i \w
(patrz tutaj )
Myślę, że najprostszym jest użycie css.
function format_str(str) {
str = str.toLowerCase();
return '<span style="text-transform: capitalize">'+ str +'</span>';
}
Służy /\S+/g
do wspierania znaków diakrytycznych:
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
Jednak: „ s unshine ( y ellow)” ⇒ „ S unshine ( y ellow)”
Chciałem dodać własną odpowiedź, ponieważ potrzebowałem solidnej toTitleCase
funkcji, która uwzględnia wymienione tutaj reguły gramatyczne (artykuł polecany przez Google). Istnieją różne reguły, które zależą od długości ciągu wejściowego. Poniżej znajduje się funkcja + testy jednostkowe.
Ta funkcja również konsoliduje białe znaki i usuwa znaki specjalne (zmodyfikuj wyrażenie regularne według swoich potrzeb)
Funkcja 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(' ');
}
Testy jednostkowe w celu zapewnienia poprawności
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');
});
});
Pamiętaj, że usuwam sporo znaków specjalnych z podanych ciągów znaków. Konieczne będzie poprawienie wyrażenia regularnego w celu spełnienia wymagań Twojego projektu.
"john f. kennedy".replace(/\b\S/g, t => t.toUpperCase())
o'henry
robi dziwne rzeczy horse's mouth
.
"john f. kennEdy".toLowerCase().replace(/\b\S/g, t => t.toUpperCase())
lepsze 🤔
\b
i \S
są specjalnymi klasami znaków oznaczającymi „granicę słów” i „pojedynczy znak spacji. Tak więc wyrażenie regularne dopasowuje każdy znak następujący po granicy słowa i dodaje ten znak wielką literą, stosując daną funkcję strzałki.
Korzystając z rozwiązania „lewax00”, stworzyłem to proste rozwiązanie, które wymusza „w” zaczynając od spacji lub „w”, które inicjują de słowo, ale nie jest w stanie usunąć dodatkowych spacji pośrednich.
"SOFÍA vergara".toLowerCase().replace(/\b(\s\w|^\w)/g, function (txt) { return txt.toUpperCase(); });
Rezultatem jest „Sofía Vergara”.
Oto moja funkcja, która zajmuje się akcentowanymi znakami (ważnymi dla francuskiego!) I która może włączać / wyłączać obsługę niższych wyjątków. Mam nadzieję, że to pomaga.
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;
}
Rozmawialiśmy tutaj, w biurze, i uważamy, że próba automatycznego poprawienia sposobu wprowadzania nazwisk w sposób, w jaki chcesz, jest obarczony potencjalnymi problemami.
Wymyśliliśmy kilka przypadków, w których różne rodzaje automatycznych wielkich liter rozpadają się i są one tylko dla angielskich nazw, każdy język ma swoją złożoność.
Problemy z pisaniem wielką literą każdej nazwy:
• Wprowadzanie akronimów takich jak IBM nie jest dozwolone, zmienia się w Ibm.
• Nazwa McDonald zmieni się w Mcdonald, co jest niepoprawne, to samo dotyczy MacDonald.
• Podwójnie nazwane nazwiska, takie jak Marie-Tonks, zamieniłyby się w Marie-tonks.
• Nazwy takie jak O'Connor zamieniłyby się w O'connor.
W przypadku większości z nich można napisać niestandardowe reguły, aby sobie z tym poradzić, jednak nadal występują problemy z akronimami, tak jak poprzednio, i pojawia się nowy problem:
• Dodanie reguły naprawy nazw w komputerach Mac, takich jak MacDonald, spowodowałoby, że nazwy przerwania, takie jak Macy, zamieniłyby je w MacY.
Jedynym wymyślonym przez nas rozwiązaniem, które nigdy nie jest niepoprawne, jest pisanie wielkimi literami, co jest metodą brutalnej siły, której wydaje się używać również DBS.
Więc jeśli chcesz zautomatyzować ten proces, najlepiej jest obejść się bez słownika dla każdej pojedynczej nazwy i słowa oraz tego, jak należy go używać wielkich liter. Jeśli nie masz reguły obejmującej wszystko, nie używaj jej w ten sposób po prostu zirytuje użytkowników i zachęci osoby, które chcą poprawnie wpisać swoje nazwisko, aby pójść gdzie indziej.
oto inne rozwiązanie za pomocą css (i javascript, jeśli tekst, który chcesz przekształcić, jest pisany wielkimi literami):
HTML
<span id='text'>JOHN SMITH</span>
js
var str = document.getElementById('text').innerHtml;
var return_text = str.toLowerCase();
css
#text{text-transform:capitalize;}
Dla tych z nas, którzy boją się wyrażeń regularnych (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(" ");
}
Moje jedno liniowe rozwiązanie:
String.prototype.capitalizeWords = function() {
return this.split(" ").map(function(ele){ return ele[0].toUpperCase() + ele.slice(1).toLowerCase();}).join(" ");
};
Następnie możesz wywołać metodę capitalizeWords()
na dowolnym ciągu. Na przykład:
var myS = "this actually works!";
myS.capitalizeWords();
>>> This Actually Works
Moje inne rozwiązanie:
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(" ");
};
Następnie możesz wywołać metodę capitalizeWords()
na dowolnym ciągu. Na przykład:
var myStr = "this one works too!";
myStr.capitalizeWords();
>>> This One Works Too
Alternatywne rozwiązanie oparte na odpowiedzi Grega Deana:
function capitalizeFirstLetter(word) {
return word[0].toUpperCase() + word.slice(1).toLowerCase();
}
String.prototype.capitalizeWords = function() {
return this.replace(/\w\S*/g, capitalizeFirstLetter);
};
Następnie możesz wywołać metodę capitalizeWords()
na dowolnym ciągu. Na przykład:
var myString = "yes and no";
myString.capitalizeWords()
>>> Yes And No
Zaskoczony, gdy nikt nie wspomniał o użyciu parametru rest. Oto prosty jednowarstwowy, który wykorzystuje parametry ES6 Rest.
let str="john smith"
str=str.split(" ").map(([firstChar,...rest])=>firstChar.toUpperCase()+rest.join("").toLowerCase()).join(" ")
console.log(str)
Jest to oparte na moim rozwiązaniu FreeFodeCamp's Bonfire „Title Case” , które wymaga, aby najpierw przekonwertować podany ciąg znaków na wszystkie małe litery, a następnie przekonwertować każdą postać poprzedzającą spację na wielkie litery.
Bez użycia wyrażenia regularnego:
function titleCase(str) {
return str.toLowerCase().split(' ').map(function(val) { return val.replace(val[0], val[0].toUpperCase()); }).join(' ');
}