Перетворити рядок у регістр заголовка за допомогою JavaScript


548

Чи є простий спосіб перетворення рядка в регістр заголовка? Напр. john smithСтає John Smith. Я не шукаю чогось такого складного, як рішення Джона Ресіга , просто (сподіваюся) якийсь одно- або дволінійний.


Існують різні методи, чи є у нас якась статистика?
theAnubhav

Будь ласка , Chech цей короткий відповідь stackoverflow.com/a/57689168/10373693 Я сподіваюся , що буде відповідь , який ви шукаєте.
Абхішек Кумар

Відповіді:


739

Спробуйте це:

    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
Чи не може хто-небудь пояснити, чому \w\S*він використовується замість цього \w+або, \w*наприклад? Я не знаю, чому ви хочете включити що-небудь, крім пробілів, і тому змінити Джим-Боба на Джим-боб .
martinczerwi

5
@martinCzerwi \w\S*також спричинив Jim-bobпроблему з нашого боку. Використовуючи \w*вирішене це.
Bouke

14
/([^\W_]+[^\s-]*) */gвирішує Jim-Bobпроблему, тобто:jim-bob --> Jim-Bob
recursion.ninja

15
Якщо jim-bob --> Jim-Bobце ваше бажання, ви, ймовірно, повинні зробити /\b\w+/g. Приклад:str.replace(/\b\w+/g,function(s){return s.charAt(0).toUpperCase() + s.substr(1).toLowerCase();});
vol7ron

3
\w\S*використовується замість \w+або \w*так , що такі слова , як Don'tне змінюйте , щоб Don'T, але , як уже зазначалося \w\S*викликає проблеми з дефісом слів.
подвійнеDown

198

Трохи більш елегантний спосіб адаптації функції Грега Діна:

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

Назвіть це так:

"pascal".toProperCase();

3
Майте на увазі , якщо у вас є користувач з тире в назві і вони входять Jo-Ann Smith, цей код буде конвертувати їх Jo-ann Smith(зверніть увагу на нижній регістр aв Ann).
dbau

18
@daniellmb Чому він не повинен змінювати прототип String? Я думаю, що це гарне рішення. Подумайте про рубінові відкриті класи, цілком справедливо додавати функції до існуючих класів, і це широко прийнято.
marco-fiset

97
@ marco-fiset Тому що він не грає добре з іншими! Погані речі трапляються, коли у вас є 2 бібліотеки, які обидва намагаються модифікувати власні об’єкти JavaScript з несумісними змінами. Уявіть, якби jQuery та Карти Google дотримувались цього шаблону дизайну, ви не могли б мати обох на одній сторінці.
daniellmb

5
@daniellmb Відмінний момент. Префіксація назви методу повинна допомогти уникнути цього, оскільки зробить метод нечислимим.
mikemaccana

60
Я відчуваю, що вислів "не змінювати рідні об’єкти JavaScript" - це як "ніколи не використовувати goto" або "eval is evil". Є маса випадків, коли це нормально. Якщо ви повністю контролюєте свій проект і, звичайно, не плануєте випускати його як бібліотеку, я не бачу проблем із цим методом.
FoxMulder900

175

Спробуйте застосувати CSS-стиль перетворення тексту до своїх елементів керування.

наприклад: (text-transform: capitalize);

Використовуйте підхід JS лише тоді, коли це абсолютно необхідно.


36
-1. Цей css працює, але не працює, як очікують більшість людей, оскільки якщо текст починається як усі літери, ефекту немає. webmasterworld.com/forum83/7506.htm
whitneyland

2
@Akshar: Мале правило буде замінено правилом регістру заголовка. Оскільки css не змінює вміст джерела, ефект полягає в тому, що правило видаляється з малого регістру (залишаючи вихідний вміст у всіх кришках), і тоді буде застосовано правило заголовка (нічого не робити).
dokkaebi

42
JS використовується поза браузерами.
mikemaccana

4
Питання було таким: "Чи є простий спосіб перетворення рядка в регістр заголовка?" . Ця відповідь не перетворює рядок. Це стиль, застосований до рядка.
kingPuppy

Якщо ви хочете, щоб дані у вашій базі даних були чистими, щоб їх можна було чисто використовувати при переході до сторонніх служб або експортувати до CSV, CSS насправді не є можливим. CSS призначений для косметики, і хоча він росте багато роками, і ви можете використовувати його для вирішення подібних проблем, рішення залишається косметичним і не вирішує основну проблему.
Адам Рейс

118

Ось моя версія, IMO легко зрозуміти і елегантно.

var str = "foo bar baz"

console.log(

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

)
// returns "Foo Bar Baz"


3
Крім того, ви можете зменшити рядки підстрочки у відображенні:str.split(' ').map(i => i[0].toUpperCase() + i.substring(1).toLowerCase()).join(' ')
Дейв Ленд

5
Я не згоден з дзвінками .toLowerCase(). Такі імена, як "McDonald" або абревіатури типу "ASAP", повинні зберігати свої великі літери. Якщо хтось насправді передав рядок типу "heLLO", додаток не повинен вважати, що великі літери неправильні.
Thomas Higginbotham

1
@ThomasHigginbotham Як щодо цього? 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(' '); }
Шон Кендл

Так, кращим є надання можливості змусити малі літери.
Thomas Higginbotham

1
Це порушиться, якщо strбуде один символ.
Madbreaks

103

Ось моя функція, яка перетворює на регістр заголовка, але також зберігає визначені абревіатури як великі, а другорядні слова як малі:

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;
}

Наприклад:

"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
Мені сподобалось ваше, я також зіткнувся з проблемами, коли маю справу з римськими номерами ... просто зафіксував це з I, II, III, IV тощо.
Marcelo

2
Виправлено. Регулярний вираз в третьому рядку було змінено /\w\S*/gна /([^\W_]+[^\s-]*) */gна @ awashburn зауваженні вище для вирішення цієї проблеми .
Джеффрі Бут

2
Чи є перевага, яку можна отримати, використовуючи ваш шаблон регулярних виразів /\b\w+/g, який я вважаю більш швидким зрозумілим?
Майкл - Де Клей Ширкий

2
Не те, що я бачу, я просто приймав пропозицію іншого коментатора, щоб вирішити проблему слово через дефіс; але, схоже, ваш регекс справляється так само добре, і простота завжди краща. Для нащадків і майбутніх відвідувачів на цю посаду, я просто змінив регулярний вираз в третьому рядку від /([^\W_]+[^\s-]*) */gдо /\b\w+/gпров @ коментар Майкла; будь ласка, прокоментуйте, якщо ви знайдете випадок, коли необхідний складніший вираз.
Джеффрі Бут

1
Я змінив регулярний вираз 3-го рядка на /\b[\w-\']+/g, щоб дозволити слова через дефіс і апостроф.
Shamasis Bhattacharya

47

Я віддаю перевагу наступному, ніж інші відповіді. Він відповідає лише першій букві кожного слова і пише його з великої літери. Простіший код, легше читати і менше байтів. Він зберігає існуючі великі літери, щоб запобігти викривленню абревіатур. Однак ви завжди можете зателефонувати toLowerCase()на свою строку спочатку.

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

Ви можете додати це до рядкового прототипу, який дозволить вам 'my string'.toTitle():

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

Приклад:


3
Ще приємніше, як лямбдаconst titleCase = (str) => str.replace(/\b\S/g, t => t.toUpperCase());
0xcaff

Я не хотів зламати IE, але так, якщо програма не є застарілим браузером, вона може бути коротшою.
Том Кей

Це лише часткове рішення - op запитав, як перетворити рядок у регістр заголовка. Ця відповідь не відповідає тому, як для вхідних даних NoT qUiITe.
Madbreaks

@Madbreaks Питання не передбачало, що змішані вхідні регістри повинні бути перетворені. Однак я оновив відповідь, згадуючи toLowerCase. Тільки майте на увазі, що це порушить абревіатури. an HTML document: An HTML DocumentvsAn Html Document
Том Кей

4
@Madbreaks Хоча ваш початковий приклад був надуманий, ви добре зазначаєте, що вихід буде не змінюватися, якби вхід був використаний з великої літери. Зважаючи на це, я вважаю, що відповідь є (з пропозицією редагування toLowerCase) більш гнучка / корисна, ніж та, яка передбачає наміри розробників. Цей метод також відображає функціональність подібних вбудованих методів інших мов, таких як PHP ( ucwords) та Golang ( strings.Title). .NET ( TextInfo.ToTitleCase) цікаво працює у змішаному регістрі, але також залишить ціліснізовані рядки незмінними.
Том Кей

20

Без використання регулярного виразу лише для довідки:

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()
)


Дякуємо за безкоштовне рішення для регулярного генерування!
lucifer63

20

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

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


Лише питання, () конструкція призначена для визначення відповідності для будь-якої послідовності варіантів: тобто, (a | b) відповідає a або b. Що робить конструкція (.)?
Майкл Блекберн

Для всіх, у кого виникло те саме питання, він визначає замінник "blob", який використовується в розділі заміни. Краплі нумеруються послідовно, перший () кладеться в $ 1, другий - в $ 2. Я вважаю цей сайт корисним: javascript.info/tutorial/regular-expressions-methods
Michael Blackburn

Я не в змозі змусити вищезазначене працювати, але я далекий від майстра регексу. Я 'string'.replace(/^(.)(.*)/,function(s,p1,p2){return p1.toUpperCase()+p2;}) знову використовую , це працює лише з великої літери першого рядка рядка, але у випадку, якщо це вам потрібно, моя конструкція працює.
Майкл Блекберн

1
Чомусь FF35, здається, захлинувся '$1'.toUpperCase(), здається, що великі регістри не були зроблені до моменту присвоєння значення. 'string'.replace(/^(.){1}/,function(match) { return match.toUpperCase(); })
Подолали,

Привіт усім, відповідь виправлена! Я майже впевнений, що він працював до моменту, коли я його спочатку розмістив. Все одно дякую за вклад!
simo

17

Ви могли одразу toLowerCaseввести рядок, а потім лише toUpperCaseпершу букву кожного слова. Стає дуже простим 1 лайнером:

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()). Мій варіант - робити те, що ви зробили, але розширюючи об’єкт String (настільки ж суперечливо):Object.defineProperty(String.prototype, '_toProperCase', {value:function() {return this.toLowerCase().replace(/\b(\w)/g, function(t) {return t.toUpperCase()})}})
Ваз

1
@Waz, дякую за ідеї! Просто хотілося уточнити =>, що це натільна функція стрілки (ES6), посилання переходить на Документи Mozillla на них, яка також містить таблицю підтримки.
KevBot

16

На випадок, якщо ви переживаєте за ці слова наповнювача, ви завжди можете просто сказати функції, що не використовувати великі літери.

/**
 * @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();
    });
};

Сподіваюсь, це допоможе тобі.

редагувати

Якщо ви хочете обробити провідні слова з клеєм, ви можете відслідковувати цю w / ще одну змінну:

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
Ви можете підірвати рядок в масив. Таким чином, ми могли мати португальські, іспанські, італійські та французькі прийменники:glue ='de|da|del|dos|do|das|des|la|della|delli'.split('|');
Junior Mayhé

Це не забезпечить написання великої літери першого слова; тобто and another thingстає and Another Thing. Просто потрібен вишуканий спосіб, щоб завжди написати великі літери першого слова.
Бред Кох

@BradKoch - килимок з пробілами, щоб ви використовували слово "і", "de" і т. Д. В якості пошукового слова, тоді "і ще одне і інше" замінять на "і ще, і інше".
Імін Ронг

добре, за винятком великої літери, також текст після 'і - як H'Dy або номер один
luky

Замість використання потрійного оператора ви можете просто використовувати резервний: glue = glue || ['of', 'for', 'і', 'a'];
tm2josep

14

Якщо регулярний вираз, який використовується у вищезазначених рішеннях, вас плутає, спробуйте цей код:

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

любити це! немає перетворення в масиви.
neelmeg

1
Уххх ... split це перетворити його в масив, ви просто не бачите його , як очевидно , тому що mapозначає , що ви не повинні використовувати []позначення
MalcolmOcean

2
Це те саме , що відповідь a8m на 2 роки раніше.
Майкл - Де Клей Ширкий

1
Перерви для одночастотних входів.
Madbreaks

1
@AlexChaffee перевірити історію редагування. a8m не використовував функцію стрілки в оригінальній відповіді.
Дякую

9

Я створив цю функцію, яка може обробляти прізвища (тому це не титульні справи), такі як "McDonald" або "MacDonald" або "O'Toole" або "D'Orazio". Однак він не обробляє німецькі та голландські імена з "ван" або "фон", які часто бувають малі ... Я вважаю, що "де" часто буває і з малих букв, таких як "Роберт де Ніро". Їх все-таки потрібно було б вирішити.

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 для усвідомлення імені. Хоча не поводиться з "macy" правильно, хоча.
бріанарі

Це була єдина функція, яка правильно обробляла перетворення великої та малої літери на правильний регістр і помічала ініціали типу "Віргінські острови США".
Родріго Поло

Ви можете обійти macyпроблему, поставивши негативний попередній там так \b((m)(a?c))?(\w)буде\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 : "");
    }
)

Здається, працює ... Перевірене вище, "швидкоплий, лисиця? / Стрибає / ^ над ^ собака ледачий ..." та "C: / програмні файли / деякий постачальник / їх 2-й додаток / file1.txt ".

Якщо ви хочете 2Nd замість другого, ви можете змінити на /([a-z])(\w*)/g .

Першу форму можна спростити як:

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

7

Спробуйте це

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

Приклад

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

7

Якщо ви можете використовувати бібліотеки сторонніх розробників у своєму коді, то lodash має для нас функцію помічника.

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

Спробуйте це найкоротшим способом:

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(' ')

ще

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

Мабуть, просто головою вгору, s.slice(0, 1).toUpperCase()якщо ви все ще хочете цього першого листа.
WindsofTime

@jssridhar також слід виправити код у ES6.
caiosm1005

1
Перерви, якщо strце один персонаж
Madbreaks

@jssridhar може бути для нас кращим .charAt(0).toUpperCase().
roydukkey

2
дублікат відповіді a8m
Дякую

6

Більшість цих відповідей, здається, ігнорують можливість використання метамехаракту слова межа (\ b). Більш коротка версія відповіді Грега Діна:

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

Працює для дефісів, як Джим-Боб.


2
Є елегантним частковим рішенням, але не працює з акцентом або великими рядками. Я отримую "Sofía Vergara" => "SofíA Vergara" або "Sofía VERGARA" => "SofíA VERGARA". Другий випадок можна вирішити за допомогою функції .toLowerCase () перед .replace (...). У першому випадку потрібно знайти правильний регулярний вираз.
Asereware

2
Гм, це здається помилкою у виконанні регулярних виразів, я думаю, що наголошені символи повинні бути символами слова (ви правдиві, так як це не працює в цих випадках).
lewax00

\wвключає лише символи [A-Za-z0-9_], не всі букви. Для цього вам потрібно буде використовувати категорію Unicode \p{L}. Вам знадобиться /uмодифікатор (див. Тут ) та інше рішення для \b, яке працює лише між \Wта \w(див. Тут )
cmbuckley

6

Я думаю, що найпростішим є використання css.

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

Я оновив код і протестував його. Це має працювати зараз.
wondim

Ви можете використовувати CSS лише у невеликій кількості середовищ, у яких використовується JS, тому це рішення не є життєздатним. Також слід уникати стилів вбудованої інформації за будь-яку ціну.
Madbreaks

5

Використовуйте /\S+/gдля підтримки діакритики:

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

Однак: " s sunhine ( y ellow)" ⇒ " S sunhine ( y ellow)"


5

Я хотів додати власну відповідь, оскільки мені потрібна була надійна toTitleCaseфункція, яка враховує правила граматики, перелічені тут (рекомендована стаття Google). Існують різні правила, які залежать від довжини вхідного рядка. Нижче наведено функцію + блок тестів.

Функція також консолідує пробіли та видаляє спеціальні символи (змінити регулярний вираз для ваших потреб)

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(' ');
}

Тести одиниць для забезпечення коректності

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');
  });
});

Зауважте, що я видаляю із спеціальних рядків зовсім небагато спеціальних символів. Вам потрібно буде підробити регулярний вираз, щоб відповідати вимогам вашого проекту.


Я вважаю за краще це рішення, оскільки воно справді піклується про правозастосовчі справи. Це не "
Знесло

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

1
Працює для зразка і o'henry, але чи не дивні речі horse's mouth.
Майкл - Де Clay

"john f. kennEdy".toLowerCase().replace(/\b\S/g, t => t.toUpperCase())краще 🤔
w3debugger

Не хотів редагувати відповідь @ Proximo: \bі \Sє спеціальні класи символів, що позначають "межу слова" та "єдиний, непробільний символ". Отже, регулярний вираз відповідає кожному символу після межі слова і використовує великі літери, застосовуючи задану функцію стрілки.
Єнс

4

Приймаючи рішення "lewax00", я створив це просте рішення, яке примушує "w" починати з простору або "w", яке починає слово, але не в змозі видалити зайві проміжні пробіли.

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

Результат - "Софія Вергара".


4

Ось моя функція, яка піклується про наголошені символи (важливо для французької мови!), Яка може вмикати / вимикати обробку винятків, що знижують. Сподіваюся, що це допомагає.

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

У нас тут в офісі ведеться дискусія, і ми думаємо, що намагання автоматично виправити те, як люди вводять імена в поточний спосіб, який ви хочете, це загрожує можливими проблемами.

Ми придумали кілька випадків, коли різні типи автоматичної написання великої літери розпадаються, і це лише для англійських імен, кожна мова має свої складності.

Проблеми з великої літери першої літери кожного імені:

• Акроніми, такі як IBM, заборонено вводити, перетворюються на Ibm.

• Ім’я Макдональд перетвориться на Макдональда, що невірно, те саме, що і Макдональд.

• Імена з подвійним стволом, такі як Марі-Тонкс, перетворюються на Марі-Тонкс.

• Такі імена, як О'Коннор, перетворяться на О'Коннор.

Для більшості з них ви можете написати спеціальні правила для вирішення цього питання, однак це все ще має проблеми з абревіатурами, як раніше, і ви отримуєте новий випуск:

• Якщо додати правило для виправлення імен за допомогою Mac, таких як MacDonald, імена перерви, такі як Macy, перетворили його на MacY.

Єдине рішення, яке ми придумали - це ніколи невірно - це використовувати великі літери, що є методом грубої сили, який, схоже, використовує і DBS.

Отже, якщо ви хочете автоматизувати процес, це так само добре, як неможливо обійтися без словника кожного окремого імені та слова, і як це слід з великої літери, якщо у вас немає правила, яке охоплює все, не використовуйте його як його просто роздратує ваших користувачів і підкаже людей, які хочуть правильно ввести свої імена, щоб піти куди-небудь ще.


4

ось ще одне рішення з використанням css (та javascript, якщо текст, який ви хочете перетворити, у верхньому регістрі):

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

Для тих із нас, хто боїться регулярних виразів (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

Моє одне рядкове рішення:

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

Потім ви можете викликати метод capitalizeWords()у будь-якій рядку. Наприклад:

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

>>> This Actually Works

Моє інше рішення:

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(" ");
};

Потім ви можете викликати метод capitalizeWords()у будь-якій рядку. Наприклад:

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

>>> This One Works Too

Альтернативне рішення на основі відповіді Грега Діна:

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

Потім ви можете викликати метод capitalizeWords()у будь-якій рядку. Наприклад:

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

>>> Yes And No

3

Здивовано, що ніхто не згадав про використання параметра відпочинку. Ось простий один вкладиш, який використовує параметри відпочинку ES6.

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


2

Це ґрунтується на моєму рішенні для багаття FreeCodeCamp "Title Case" , яке вимагає, щоб ви спочатку перетворили заданий рядок у всі малі регістри, а потім перетворили кожен символ, що протікає пробілом, у верхній регістр.

Без використання регулярного вираження:

function titleCase(str) {
 return str.toLowerCase().split(' ').map(function(val) { return val.replace(val[0], val[0].toUpperCase()); }).join(' ');
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.