Как сделать первую букву строки заглавной в JavaScript?

3767

Как сделать первую букву строки заглавной, но не изменить регистр любой другой буквы?

Например:

  • "this is a test" -> "This is a test"
  • "the Eiffel Tower" -> "The Eiffel Tower"
  • "/index.html" -> "/index.html"
Роберт Уиллс
источник
12
У Underscore есть плагин underscore.string, который включает в себя это и множество других замечательных инструментов.
Аарон
А как насчет:return str.replace(/(\b\w)/gi,function(m){return m.toUpperCase();});
Мухаммед Умер
111
Проще:string[0].toUpperCase() + string.substring(1)
др.димитру
7
`${s[0].toUpperCase()}${s.slice(1)}`
noego
([initial, ...rest]) => [initial.toUpperCase(), ...rest].join("")
Константин Ван

Ответы:

5813

Основное решение:

function capitalizeFirstLetter(string) {
  return string.charAt(0).toUpperCase() + string.slice(1);
}

console.log(capitalizeFirstLetter('foo')); // Foo

Некоторые другие ответы изменяются String.prototype(этот ответ также использовался), но я бы посоветовал против этого сейчас из-за удобства сопровождения (сложно определить, куда добавляется функция, prototypeи может вызвать конфликты, если другой код использует то же имя / браузер добавляет нативную функцию с тем же именем в будущем).

... и затем, когда вы рассматриваете интернационализацию, в этом вопросе есть еще много всего, как показывает этот удивительно хороший ответ (похоронен ниже).

Если вы хотите работать с кодовыми точками Unicode вместо кодовых единиц (например, для обработки символов Unicode вне Базовой многоязычной плоскости), вы можете использовать тот факт, что String#[@iterator]работает с кодовыми точками, и вы можете использовать toLocaleUpperCaseдля получения корректного локали в верхнем регистре:

function capitalizeFirstLetter([ first, ...rest ], locale = navigator.language) {
  return [ first.toLocaleUpperCase(locale), ...rest ].join('');
}

console.log(capitalizeFirstLetter('foo')); // Foo
console.log(capitalizeFirstLetter("𐐶𐐲𐑌𐐼𐐲𐑉")); // "𐐎𐐲𐑌𐐼𐐲𐑉" (correct!)
console.log(capitalizeFirstLetter("italya", 'tr')); // İtalya" (correct in Turkish Latin!)

Для еще большего количества вариантов интернационализации, пожалуйста, смотрите оригинальный ответ ниже .

Стив Харрисон
источник
9
подстрока понимается в большем количестве браузеров, чем
подстр
6
добавить в karim79 - возможно, излишне делать его функцией, поскольку javascript сделает то же самое с переменной без переноса функции. Я полагаю, было бы более понятно, используя функцию, но в противном случае ее родную, зачем усложнять ее с помощью обертки функции?
Росс
18
Не должны ли мы также уменьшить размер среза (1)?
hasen
177
Нет, потому что ОП привел этот пример: the Eiffel Tower -> The Eiffel Tower. Плюс функция называется capitaliseFirstLetterне так capitaliseFirstLetterAndLowerCaseAllTheOthers.
запрет геоинженерии
22
Никого не волнует важное правило ООП? - Никогда не редактировать объекты, которые вам не принадлежат? , Кстати, этот однострочник выглядит намного элегантнее:string[0].toUpperCase() + string.substring(1)
dr.dimitru
1350

Вот более объектно-ориентированный подход:

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

Вы бы вызвали функцию, вот так:

"hello world".capitalize();

Ожидаемый результат:

"Hello world" 
Стив Ханселл
источник
24
Мне нравится это решение, потому что оно похоже на Ruby, а Ruby сладок! :) Я строчные буквы всех других букв строки так, чтобы она return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
работала
164
В этом мире пост-Prototype.js не предлагается изменять или расширять собственные объекты.
Райан
191
@rxgx - бугмен "не расширять" теперь начинает отмирать (слава богу), и люди вытаскивают свои головы из jSand и понимают, что это всего лишь языковая функция. Тот факт, что Prototype.js на короткое время расширил сам объект, не означает, что расширение Native - это плохо. Вам не следует делать это, если вы пишете код для неизвестного потребителя (например, сценарий аналитики, работающий на случайных сайтах), но в остальном это нормально.
csuwldcat
44
@csuwldcat Что делать, если другая используемая вами библиотека добавляет собственную заглавную букву без вашего ведома? Расширение прототипов - плохая форма, независимо от того, делал это Prototype.js или нет. С ES6 встроенные функции позволят вам съесть свой торт и съесть его тоже. Я думаю, вы могли бы запутать, что «бугмен» умирает за людей, создающих прокладки, которые соответствуют спецификации ECMASCRIPT. Эти прокладки отлично подходят, потому что другая библиотека, которая добавила прокладку, реализовала бы ее таким же образом. Тем не менее, добавление ваших собственных не-спецификаций следует избегать.
Джастин Мейер
44
Расширение аборигенов ЧРЕЗВЫЧАЙНО плохая практика. Даже если вы скажете «о, я никогда не собираюсь использовать этот код с чем-либо еще», вы (или кто-то еще), вероятно, будете. Затем они потратят три дня, пытаясь выяснить какую-то странную математическую ошибку, потому что кто-то расширил Number.money (), чтобы иметь дело с валютой, немного отличающейся от вашей другой библиотеки. Серьезно, я видел, как это происходит в большой компании, и не стоит никому отлаживать, чтобы выяснить, какая библиотека работает с прототипами туземцев.
phreakhead
574

В CSS:

p:first-letter {
    text-transform:capitalize;
}
sam6ber
источник
80
ОП запрашивает решение JS.
Антонио Макс
129
. $ ( '# mystring_id') текст (строка) .css ( 'текст-преобразования', 'выгоду');
ДонМБ
21
Кроме того, это влияет только на отображение строки, а не на фактическое значение. Если это в форме, например, значение все равно будет представлено как есть.
Дмансфилд
12
Этот ответ помог мне понять, что решение CSS действительно больше подходит для того, что я делаю. @dudewad: Ответ, вероятно, должен дать отказ от ответственности, что это не решение JS, но может быть более подходящим в зависимости от необходимости.
января
58
Для примерно 80% зрителей, пришедших на этот вопрос, это будет лучшим ответом. Не ответ на вопрос , а на проблему .
Дживан
290

Вот сокращенная версия популярного ответа, который получает первую букву, рассматривая строку как массив:

function capitalize(s)
{
    return s[0].toUpperCase() + s.slice(1);
}

Обновить:

Согласно комментариям ниже, это не работает в IE 7 или ниже.

Обновление 2:

Чтобы избежать undefinedпустых строк (см . Комментарий @ njzk2 ниже ), вы можете проверить наличие пустой строки:

function capitalize(s)
{
    return s && s[0].toUpperCase() + s.slice(1);
}
joelvh
источник
23
Это не будет работать в IE <8, так как эти браузеры не поддерживают индексацию строк. Сам IE8 поддерживает это, но только для строковых литералов - не для строковых объектов.
Матиас Биненс,
52
Кому интересно, рынок IE7 составляет менее 5%! и это, вероятно, старая машина твоей Греммы и Гремпы. Я говорю короткий код FTW!
vsync
@MathiasBynens Знаете ли вы, затрагивает ли это какие-либо старые браузеры не IE или просто IE7? Если в 2014 году индексирование строковых литералов не затронуло ни один другой браузер, все будет в порядке. :)
hexalys
3
@vsync Я просто имел в виду, что в зависимости от вашей демографии пользователей, иногда (хотя с благодарностью все меньше и меньше по мере того, как мы проходим 2014 год и далее), выгодно поддерживать старые браузеры, такие как IE7 ...
joshuahedlund
2
@ njzk2, чтобы обработать пустую строку, вы можете обновить это: return s && s[0].toUpperCase() + s.slice(1);
joelvh
188

Если вы заинтересованы в производительности нескольких различных методов, опубликованных:

Вот самые быстрые методы, основанные на этом тесте jsperf (упорядоченные от самого быстрого до самого медленного).

Как вы можете видеть, первые два метода по существу сопоставимы с точки зрения производительности, тогда как изменение String.prototypeявляется самым медленным с точки зрения производительности.

// 10,889,187 operations/sec
function capitalizeFirstLetter(string) {
    return string[0].toUpperCase() + string.slice(1);
}

// 10,875,535 operations/sec
function capitalizeFirstLetter(string) {
    return string.charAt(0).toUpperCase() + string.slice(1);
}

// 4,632,536 operations/sec
function capitalizeFirstLetter(string) {
    return string.replace(/^./, string[0].toUpperCase());
}

// 1,977,828 operations/sec
String.prototype.capitalizeFirstLetter = function() {
    return this.charAt(0).toUpperCase() + this.slice(1);
}

введите описание изображения здесь

Джош Крозье
источник
1
Кажется, код инициализации тоже не имеет значения: jsperf.com/capitalize-first-letter-of-string/2
user420667
6
Также обратите внимание, что замена .slice(1)на .substr(1)это повысит производительность еще больше.
Przemek
2
Разумное рассмотрение. Имейте в виду, что во многих случаях снижение производительности даже не заметно: даже самый медленный подход будет обрабатывать 19 тыс. Строк за 10 мс. Поэтому возьмите наиболее удобный для вас вариант.
Цитируя Эдди
1
В случае, если кому-то интересно (как и мне), как за последние четыре года производительность увеличилась, число операций в секунду для третьей функции на MacBook Pro 2018 года составляет 135 307 869, то есть, по существу, в 12,4 раза быстрее.
Карло Филд
151

В другом случае мне нужно, чтобы первая буква была заглавной, а остальные строчными. Следующие случаи заставили меня изменить эту функцию:

//es5
function capitalize(string) {
    return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();
}
capitalize("alfredo")  // => "Alfredo"
capitalize("Alejandro")// => "Alejandro
capitalize("ALBERTO")  // => "Alberto"
capitalize("ArMaNdO")  // => "Armando"

// es6 using destructuring 
const capitalize = ([first,...rest]) => first.toUpperCase() + rest.join('').toLowerCase();
Alejandro
источник
1
msgstr "... но не меняйте регистр других букв". Это не правильный ответ на вопрос, заданный ОП.
Карлос Муньос
2
@ CarlosMuñoz, если вы прочитаете вступительное предложение, он говорит, что это для другого случая.
TMH
3
@ TomHart Именно поэтому это не решение вопроса. Это должен быть комментарий или другой вопрос и ответ
Карлос Муньос
15
Я согласен с вами в этом, но я вижу, что многие люди заканчивают здесь, пытаясь сделать то, что делает этот ответ.
TMH
74

Это решение ECMAScript 6+ 2018 года :

const str = 'the Eiffel Tower';
const newStr = `${str[0].toUpperCase()}${str.slice(1)}`;
console.log('Original String:', str); // the Eiffel Tower
console.log('New String:', newStr); // The Eiffel Tower

Стерлинг борн
источник
5
.slice()медленнее, чем .substring(), str[0]будет undefinedдля пустой строки и использование литералов шаблона для объединения двух частей вводит здесь 8 символов, а +вводит только 3.
Przemek
4
Цель моего ответа Prz - продемонстрировать новые поддерживаемые функции ES6, в частности литералы шаблонов, которые не упоминались в других публикациях. Идея StackOverflow состоит в том, чтобы предоставить поисковику «опции». Они могут взять концепцию литералов шаблонов, описанную в этом ответе, и объединить ее с улучшениями микроскорости, такими как Substring v. Slice, если их приложению требуются эти дополнительные сэкономленные миллисекунды. Мой ответ также не включает юнит-тестирование, которое показывает, что вы никогда не должны копировать и вставлять ответ StackOverflow напрямую. Я предполагаю, что разработчик примет мой ответ и адаптирует его.
Стерлинг Борн
Вы ничего не получаете от использования литералов шаблона здесь, а ${}просто добавляет шума. const newStr = str[0].toUpperCase() + str.slice(1);легче читать.
Борис
1
Согласитесь тогда не соглашаться с тем, что легче читать.
Стерлинг Борн
67

Если вы уже (или рассматриваете) использование lodash, решение легко:

_.upperFirst('fred');
// => 'Fred'

_.upperFirst('FRED');
// => 'FRED'

_.capitalize('fred') //=> 'Fred'

Смотрите их документы: https://lodash.com/docs#capitalize

_.camelCase('Foo Bar'); //=> 'fooBar'

https://lodash.com/docs/4.15.0#camelCase

_.lowerFirst('Fred');
// => 'fred'

_.lowerFirst('FRED');
// => 'fRED'

_.snakeCase('Foo Bar');
// => 'foo_bar'

Ваниль JS для первого верхнего регистра:

function upperCaseFirst(str){
    return str.charAt(0).toUpperCase() + str.substring(1);
}
chovy
источник
11
Я думаю, что предпочтение следует отдавать ванильным Js, так как большинство людей не будут загружать весь фреймворк только для того, чтобы использовать строку.
GGG
7
Пока что во всех моих проектах я никогда не использовал lodash. Не забывайте также, что большинство людей в Google заканчивают на этой странице, и перечисление фреймворка в качестве альтернативы хорошо, но не как основной ответ.
GGG
2
Поскольку другие ответы используют vanilla js, было бы неплохо иметь такой ответ, поскольку многие из нас используют lodash / underscore.
Лу Роман
1
Это не правильный ответ, так как OP сейчас просит это сделать в Javascript, а не в библиотеке Javascript, которая импортирует всю библиотеку как зависимость от вашего проекта. Не используйте это.
dudewad
1
В конце моего ответа вопрос ОП стоит в ванили.
Чови
62

Прописать первую букву всех слов в строке:

function ucFirstAllWords( str )
{
    var pieces = str.split(" ");
    for ( var i = 0; i < pieces.length; i++ )
    {
        var j = pieces[i].charAt(0).toUpperCase();
        pieces[i] = j + pieces[i].substr(1);
    }
    return pieces.join(" ");
}
Дэн
источник
14
Перечитайте вопрос: я хочу использовать заглавные буквы в первом символе строки, но не менять регистр других букв.
JimmyPena
2
Я знаю, что сделал. Я бы добавил одну вещь, если вся строка начинается с заглавной буквы :iece [i] = j +iece [i] .substr (1) .toLowerCase ();
Малович
4
Другое решение этого случая: функция capitaliseFirstLetters (s) {return s.split ("") .map (function (w) {return w.charAt (0) .toUpperCase () + w.substr (1)}). Join ("")} Может быть хорошим однострочником, если он не включен в функцию.
Люк Ченнингс
Было бы лучше, чтобы в первую очередь строчная вся строка
Magico
Кроме этой функции, не отвечающей на вопрос, на самом деле она также слишком сложна. s => s.split(' ').map(x => x[0].toUpperCase() + x.slice(1)).join(' ')
OverCoder
48

Мы могли бы получить первого персонажа с одним из моих любимых RegExp, похожим на милый смайлик:/^./

String.prototype.capitalize = function () {
  return this.replace(/^./, function (match) {
    return match.toUpperCase();
  });
};

И для всех любителей кофе:

String::capitalize = ->
  @replace /^./, (match) ->
    match.toUpperCase()

... и для всех парней, которые думают, что есть лучший способ сделать это без расширения собственных прототипов:

var capitalize = function (input) {
  return input.replace(/^./, function (match) {
    return match.toUpperCase();
  });
};
yckart
источник
2
Есть лучший способ сделать это без изменения прототипа String.
Big McLargeHuge
2
@ davidkennedy85 Конечно! Но это простой, а не лучший способ ... ;-)
yckart
Дорогой лорд, на этот вопрос миллион ответов! Ваше решение выглядит еще лучше в es6. 'Answer'.replace(/^./, v => v.toLowerCase())
stwilz
47

Использование:

var str = "ruby java";

console.log(str.charAt(0).toUpperCase() + str.substring(1));

Он выведет "Ruby java"на консоль.

AMIC MING
источник
Одноканальное решение.
Ахмад Шариф
45

Если вы используете underscore.js или Lo-Dash , библиотека underscore.string предоставляет расширения строк, включая прописные:

_.capitalize (string) Преобразует первую букву строки в верхний регистр.

Пример:

_.capitalize("foo bar") == "Foo bar"
andersh
источник
3
Начиная с версии 3.0.0 , в Lo-Dash этот строковый метод доступен по умолчанию. Так же, как описано в этом ответе _.capitalize("foo") === "Foo".
Бардзусный
Также есть полезная функция underscore.js humanize. Он преобразует подчеркнутую, верблюжью или разбитую строку в гуманизированную. Также удаляет начальные и конечные пробелы и удаляет постфикс «_id».
Степан Захаров
1
Начиная с версии 4 *, Lodash также строчные буквы () все остальные буквы, будьте осторожны!
Игорь Лоскутов
45
String.prototype.capitalize = function(allWords) {
   return (allWords) ? // if all words
      this.split(' ').map(word => word.capitalize()).join(' ') : //break down phrase to words then  recursive calls until capitalizing all words
      this.charAt(0).toUpperCase() + this.slice(1); // if allWords is undefined , capitalize only the first word , mean the first char of the whole string
}

А потом:

 "capitalize just the first word".capitalize(); ==> "Capitalize just the first word"
 "capitalize all words".capitalize(true); ==> "Capitalize All Words"

Обновление ноябрь 2016 (ES6), просто для удовольствия:

const capitalize = (string = '') => [...string].map(    //convert to array with each item is a char of string by using spread operator (...)
    (char, index) => index ? char : char.toUpperCase()  // index true means not equal 0 , so (!index) is the first char which is capitalized by `toUpperCase()` method
 ).join('')                                             //return back to string

тогда capitalize("hello") // Hello

Абденнур ТУМИ
источник
3
Я думаю, что это плохое решение по двум причинам: изменение прототипа примитива - плохая идея. Если спецификация меняется, и они решают выбрать «заглавные буквы» в качестве нового имени свойства прото, вы нарушаете функциональность основного языка. Кроме того, выбранное имя метода плохое. На первый взгляд, я думаю, это заглавная строка. Лучше было бы использовать более описательное имя, такое как PHP ucFirst или что-то подобное.
dudewad
Другой ES6 ответ проще: const capitalize = ([first,...rest]) => first.toUpperCase() + rest.join('').toLowerCase();.
Дан Даскалеску
44

Кратчайшие 3 решения, 1 и 2 обрабатывают случаи, когда sстрока есть "", nullи undefined:

 s&&s[0].toUpperCase()+s.slice(1)        // 32 char

 s&&s.replace(/./,s[0].toUpperCase())    // 36 char - using regexp

'foo'.replace(/./,x=>x.toUpperCase())    // 31 char - direct on string, ES6

Камил Келчевски
источник
42

Только CSS

p::first-letter {
  text-transform: uppercase;
}
  • Несмотря на вызов ::first-letter, он применяется к первому символу , т. Е. В случае строки %a, этот селектор будет применяться %и как таковой aне будет написан заглавными буквами.
  • В IE9 + или IE5.5 + это поддерживается в устаревшей нотации только с одним двоеточием ( :first-letter).

ES2015 однострочный

Поскольку существует множество ответов, но в ES2015 нет ни одного, который бы эффективно решал исходную проблему, я придумал следующее:

const capitalizeFirstChar = str => str.charAt(0).toUpperCase() + str.substring(1);

замечания

  • parameters => functionэто так называемая функция стрелки .
  • Я пошел с именем capitalizeFirstCharвместо capitalizeFirstLetter, потому что OP не запрашивал код, который использует первую букву во всей строке, а самый первый символ (если, конечно, это буква).
  • constдает нам возможность объявлять capitalizeFirstCharкак константу, что желательно, поскольку как программист вы всегда должны явно указывать свои намерения.
  • В тесте, который я выполнил, не было существенной разницы между string.charAt(0)и string[0]. Однако обратите внимание, что string[0]это будет undefinedдля пустой строки, поэтому ее следует переписать в string && string[0]слишком многословно по сравнению с альтернативой.
  • string.substring(1)быстрее чем string.slice(1).

эталонный тест

  • 4,956,962 ops / s ± 3,03% для этого решения,
  • 4,577,946 операций / с ± 1,2% для наиболее проголосовавшего ответа.
  • Создано с помощью JSBench.me в Google Chrome 57.

Сравнение решений

Przemek
источник
@Green: да , вы уверены, что указали селектор с двумя двоеточиями?
Przemek
1
Вы на самом деле не хотите использовать знак плюс (+) в качестве метода конкатенации в ES6. Вы захотите использовать шаблоны литералов: eslint.org/docs/rules/prefer-template
Стерлинг Борн
42

Существует очень простой способ реализовать его путем замены . Для ECMAScript 6:

'foo'.replace(/^./, str => str.toUpperCase())

Результат:

'Foo'
Литл Ройс
источник
1
Лучший ответ на данный момент, и дополнительные очки за показ синтаксиса регулярных выражений лямбда-выражений. Мне особенно нравится этот, поскольку это может быть беглый вырезать и вставить в любом месте.
Уэйд Хэтлер
Использование /^[a-z]/iбудет лучше, чем использование, так .как предыдущий не будет пытаться заменить любой другой символ, кроме алфавита
Code Maniac
39

Я не видел никаких упоминаний в существующих ответах на вопросы, касающиеся кодовых точек астрального плана или интернационализации. «Прописные буквы» не означают одно и то же в каждом языке, использующем данный скрипт.

Изначально я не видел ответов на вопросы, связанные с кодовыми точками астрального плана. Там является один , но это немного похоронен (как это один будет, я думаю!)


Большинство предлагаемых функций выглядят так:

function capitalizeFirstLetter(str) {
  return str[0].toUpperCase() + str.slice(1);
}

Тем не менее, некоторые прописные символы находятся за пределами BMP (базовая многоязычная плоскость, кодовые точки от U + 0 до U + FFFF). Например, возьмите этот текст Deseret:

capitalizeFirstLetter("𐐶𐐲𐑌𐐼𐐲𐑉"); // "𐐶𐐲𐑌𐐼𐐲𐑉"

Первый символ здесь не может быть написан заглавными буквами, потому что индексированные по массиву свойства строк не имеют доступа к «символам» или кодовым точкам *. Они имеют доступ к кодовым единицам UTF-16. Это верно и при разрезании - значения индекса указывают на единицы кода.

Случается, что кодовые единицы UTF-16 имеют размер 1: 1 с кодовыми точками USV в двух диапазонах, от U + 0 до U + D7FF и от U + E000 до U + FFFF включительно. Большинство описанных персонажей попадают в эти два диапазона, но не все.

С ES2015 справиться с этим стало немного легче. String.prototype[@@iterator]дает строки, соответствующие кодовым точкам **. Так, например, мы можем сделать это:

function capitalizeFirstLetter([ first, ...rest ]) {
  return [ first.toUpperCase(), ...rest ].join('');
}

capitalizeFirstLetter("𐐶𐐲𐑌𐐼𐐲𐑉") // "𐐎𐐲𐑌𐐼𐐲𐑉"

Для более длинных строк это, вероятно, не очень эффективно *** - нам не нужно итерировать остаток. Мы могли бы использовать, String.prototype.codePointAtчтобы получить это первое (возможное) письмо, но нам все еще нужно было бы определить, где должен начинаться срез. Один из способов избежать итерации остатка - проверить, находится ли первая кодовая точка вне BMP; если это не так, срез начинается с 1, а если это так, срез начинается с 2.

function capitalizeFirstLetter(str) {
  const firstCP = str.codePointAt(0);
  const index = firstCP > 0xFFFF ? 2 : 1;

  return String.fromCodePoint(firstCP).toUpperCase() + str.slice(index);
}

capitalizeFirstLetter("𐐶𐐲𐑌𐐼𐐲𐑉") // "𐐎𐐲𐑌𐐼𐐲𐑉"

Вы могли бы использовать побитовую математику вместо > 0xFFFFэтого, но, вероятно, легче понять этот путь, и любой из них достиг бы того же самого.

Мы также можем сделать эту работу в ES5 и ниже, взяв эту логику немного дальше, если это необходимо. В ES5 нет встроенных методов для работы с кодовыми точками, поэтому мы должны вручную проверить, является ли первая единица кода суррогатом ****:

function capitalizeFirstLetter(str) {
  var firstCodeUnit = str[0];

  if (firstCodeUnit < '\uD800' || firstCodeUnit > '\uDFFF') {
    return str[0].toUpperCase() + str.slice(1);
  }

  return str.slice(0, 2).toUpperCase() + str.slice(2);
}

capitalizeFirstLetter("𐐶𐐲𐑌𐐼𐐲𐑉") // "𐐎𐐲𐑌𐐼𐐲𐑉"

В начале я также упомянул соображения интернационализации. Некоторые из них очень трудно объяснить, потому что они требуют знания не только того, какой язык используется, но также могут требовать определенных знаний слов в языке. Например, ирландский орграф "mb" пишется с заглавной буквы как "mB" в начале слова. Другой пример, немецкий eszett, никогда не начинает слово (afaik), но все же помогает проиллюстрировать проблему. Строчные буквы eszett («ß») пишутся с заглавной буквы «SS», но «SS» может быть строчными или «ß», или «ss» - вам необходимо внеполосное знание немецкого языка, чтобы знать, что правильно!

Наиболее известный пример такого рода проблем, вероятно, турецкий. В турецкой латыни заглавная форма i - это İ, а строчная форма I - ı - это две разные буквы. К счастью, у нас есть способ объяснить это:

function capitalizeFirstLetter([ first, ...rest ], locale) {
  return [ first.toLocaleUpperCase(locale), ...rest ].join('');
}

capitalizeFirstLetter("italy", "en") // "Italy"
capitalizeFirstLetter("italya", "tr") // "İtalya"

В браузере наиболее предпочтительный языковой тег пользователя обозначен значком navigator.language, в нем находится список в порядке предпочтения navigator.languages, а язык данного элемента DOM может быть получен (обычно) Object(element.closest('[lang]')).lang || YOUR_DEFAULT_HEREв многоязычных документах.

В агентах, которые поддерживают классы символов свойств Unicode в RegExp, которые были представлены в ES2018, мы можем очистить вещи дальше, напрямую выражая, какие символы нас интересуют:

function capitalizeFirstLetter(str, locale=navigator.language) {
  return str.replace(/^\p{CWU}/u, char => char.toLocaleUpperCase(locale));
}

Это можно немного подправить, чтобы обрабатывать несколько слов в строке с большой точностью. CWUИли Changes_When_Uppercased свойство символов соответствует всем точкам кода , которые, ну, когда изменения в верхнем регистре. Мы можем попробовать это с помощью заглавных букв, таких как голландский ij, например:

capitalizeFirstLetter('ijsselmeer'); // "IJsselmeer"

На момент написания статьи (февраль 2020 г.) Firefox / Spidermonkey еще не реализовал ни одной из функций RegExp, представленных за последние два года *****. Вы можете проверить текущее состояние этой функции в таблице сравнения Kangax . Babel может компилировать литералы RegExp со ссылками на свойства для эквивалентных шаблонов без них, но имейте в виду, что результирующий код может быть огромным.


По всей вероятности, люди, задающие этот вопрос, не будут беспокоиться о капитализации или интернационализации Deseret. Но хорошо знать об этих проблемах, потому что есть большая вероятность, что вы в конечном итоге столкнетесь с ними, даже если в настоящее время они не являются проблемой. Это не «крайние» случаи, или, скорее, они не являются крайними случаями по определению - во всяком случае, существует целая страна, где большинство людей говорят по-турецки, и объединение блоков кода с кодовыми точками является довольно распространенным источником ошибок (особенно в что касается смайликов). И строки, и язык довольно сложны!


* Кодовые единицы UTF-16 / UCS2 также являются кодовыми точками Unicode в том смысле, что, например, U + D800 технически является кодовой точкой, но это не то, что здесь «означает» ... вроде ... хотя это и получается довольно нечеткая. Что суррогаты определенно не являются, тем не менее, являются USV (скалярные значения Unicode).

** Хотя, если единица суррогатного кода «осиротела», то есть не является частью логической пары, вы все равно можете получить здесь и суррогаты.

*** может быть. Я не проверял это. Если вы не определили, что использование заглавных букв является значительным узким местом, я бы, наверное, не потел бы с этим - выбирайте то, что вы считаете наиболее понятным и читабельным.

**** такая функция может захотеть проверить как первую, так и вторую кодовые единицы, а не только первую, поскольку вполне возможно, что первая единица является суррогатом-сиротой. Например, ввод «\ uD800x» будет использовать заглавную букву X как есть, чего можно ожидать или не ожидать.

***** Вот проблема Bugzilla, если вы хотите следить за прогрессом более непосредственно.

Точка с запятой
источник
2
Этот ответ нужно перенести на передний план.
Рунар Берг
Спасибо @ RúnarBerg - так как ваш комментарий напомнил мне об этом, я перечитал его еще раз и понял, что упустил окончательный вариант и решение, которое стоит упомянуть. Также попытался уточнить некоторые термины лучше.
точка с запятой
Отличный ответ .....
Бен Астон
Этот ответ превосходен, я бы хотел, чтобы я проголосовал за него больше.
Дэвид Баркер
38

В CSS это выглядит проще:

<style type="text/css">
    p.capitalize {text-transform:capitalize;}
</style>
<p class="capitalize">This is some text.</p>

Это из CSS text-transform PropertyW3Schools ).

Райан
источник
29
@Simon Не указано, что строка обязательно будет выводиться как часть HTML-документа - CSS будет полезен только в том случае, если он есть.
Адам Хептон
9
Адам, правда, но я предполагаю, что более 95% Javascript там используется с HTML и CSS. К сожалению, оператор «прописные» на самом деле использует заглавные буквы в каждом слове , поэтому вам все равно понадобится JS, чтобы использовать только первую букву строки.
Саймон Ист
18
Неправильно, Динеш. Он сказал первый символ строки .
Саймон Ист
81
Этот ответ, несмотря на нелепое количество голосов, просто неверен, так как он будет использовать первую букву каждого слова. @ Райан, вы получите значок дисциплины, если удалите его. Пожалуйста, сделай так.
Дан Даскалеску
10
Согласитесь с @DanDascalescu - ответ Райана совершенно неправильный.
Тимо
38
var capitalized = yourstring[0].toUpperCase() + yourstring.substr(1);
zianwar
источник
37

Всегда лучше сначала обрабатывать такие вещи с помощью CSS , в общем, если вы можете решить что-то с помощью CSS, сначала сделайте это, затем попробуйте JavaScript, чтобы решить ваши проблемы, поэтому в этом случае попробуйте использовать :first-letterв CSS и применитьtext-transform:capitalize;

Так что попробуйте создать класс для этого, чтобы вы могли использовать его глобально, например: .first-letter-uppercaseи добавить что-то вроде ниже в свой CSS:

.first-letter-uppercase:first-letter {
    text-transform:capitalize;
}

Также альтернативным вариантом является JavaScript, поэтому лучше всего будет что-то вроде этого:

function capitalizeTxt(txt) {
  return txt.charAt(0).toUpperCase() + txt.slice(1); //or if you want lowercase the rest txt.slice(1).toLowerCase();
}

и назовите это как:

capitalizeTxt('this is a test'); // return 'This is a test'
capitalizeTxt('the Eiffel Tower'); // return 'The Eiffel Tower'
capitalizeTxt('/index.html');  // return '/index.html'
capitalizeTxt('alireza');  // return 'Alireza'

Если вы хотите использовать его снова и снова, лучше присоединить его к нативной String javascript, так что-то вроде ниже:

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

и назовите это как ниже:

'this is a test'.capitalizeTxt(); // return 'This is a test'
'the Eiffel Tower'.capitalizeTxt(); // return 'The Eiffel Tower'
'/index.html'.capitalizeTxt();  // return '/index.html'
'alireza'.capitalizeTxt();  // return 'Alireza'
Алиреза
источник
36

Если вы хотите переформатировать весь заглавные буквы, вы можете изменить другие примеры следующим образом:

function capitalize (text) {
    return text.charAt(0).toUpperCase() + text.slice(1).toLowerCase();
}

Это обеспечит изменение следующего текста:

TEST => Test
This Is A TeST => This is a test
monokrome
источник
Вероятно, стоит отметить, что это также преобразует такие вещи, как аббревиатуры, в нижний регистр, так что, возможно, не самая лучшая идея в большинстве случаев
монокром
Кроме того, действительно ли GAMITG внес изменения, просто чтобы удалить часть пробела из некодовой части сообщения? О_О
монокром
Кстати, это нарушит прописные аббревиатуры, так что будьте осторожны, вы все <3
монокром
34
function capitalize(s) {
    // returns the first letter capitalized + the string from index 1 and out aka. the rest of the string
    return s[0].toUpperCase() + s.substr(1);
}


// examples
capitalize('this is a test');
=> 'This is a test'

capitalize('the Eiffel Tower');
=> 'The Eiffel Tower'

capitalize('/index.html');
=> '/index.html'
Фредрик А.
источник
Готово @Ram. Также включены примеры.
Фредрик А.
Чем это лучше ответа 2009 года ?
Дан Даскалеску
1
Это не @DanDascalescu. Я полагаю, вы могли бы утверждать, что substr/ substringнемного более семантически, чем это slice, но это просто вопрос предпочтений. Тем не менее, я включил примеры со строками, приведенными в вопросе, что приятно, но не в примере '09. Я, честно говоря, считаю, что 15-летняя я хочу карму на StackOverflow;)
Фредрик А.
34

Вот функция ucfirst () (сокращение от «первая буква верхнего регистра»):

function ucfirst(str) {
    var firstLetter = str.substr(0, 1);
    return firstLetter.toUpperCase() + str.substr(1);
}

Вы можете использовать строку с заглавной буквы, вызывая ucfirst («некоторая строка») - например,

ucfirst("this is a test") --> "This is a test"

Это работает, разделив строку на две части. В первой строке он извлекает firstLetter, а затем во второй строке он использует прописную букву firstLetter , вызывая firstLetter.toUpperCase (), и соединяет его с остальной частью строки, которая определяется путем вызова str.substr (1) .

Вы можете подумать, что это не сработает для пустой строки, и на самом деле на языке, подобном C, вам придется учитывать это. Однако в JavaScript, когда вы берете подстроку пустой строки, вы просто возвращаете пустую строку.

Роберт Уиллс
источник
4
Используйте String.substring () или String.slice () ... Не используйте substr () - это не рекомендуется.
Джеймс
7
@ 999: где говорится, что substr()это устарело? Это даже не сейчас, три года спустя, не говоря уже о том, чтобы в 2009 году вы сделали этот комментарий.
Дан Даскалеску
substr()может не помечаться как устаревшая в любой популярной реализации ECMAScript (я сомневаюсь, что она не исчезнет в ближайшее время), но это не является частью спецификации ECMAScript. Третье издание спецификации упоминает его в ненормативном приложении, чтобы «предложить единую семантику для таких свойств, не делая свойства или их семантику частью этого стандарта».
Питер Руст
2
Имея 3 методы , которые делают то же самое ( substring, substrи slice) слишком много, ИМО. Я всегда использую, sliceпотому что он поддерживает отрицательные индексы, у него нет запутывающего поведения подстановки аргументов, и его API похож на sliceдругие языки.
Питер Руст
29
String.prototype.capitalize = function(){
    return this.replace( /(^|\s)([a-z])/g , function(m,p1,p2){ return p1+p2.toUpperCase();
    } );
};

Применение:

capitalizedString = someString.capitalize();

Это текстовая строка => Это текстовая строка

Мурат Кукукосман
источник
20
Регулярные выражения для этого излишни.
Энтони Соттил
+1, это то, что я действительно искал. Есть небольшая ошибка, хотя, это должно быть return.this.toLocaleLowerCase().replace(...
tomdemuyt
+1, я нашел эту страницу в поисках javascript-версии phps ucfirst, которая, как я подозреваю, такова, как ее находит большинство людей.
Benubird
@DanDascalescu Я нашел это полезным, так что +1 утилитаризм и -1 анальная сохранность. Он включил пример, поэтому его функция понятна.
Трэвис Уэбб
String.prototype.capitalize = function(){ return this.replace( /(^|\s)[a-z]/g , function(m){ return m.toUpperCase(); }); }; Я немного рефакторинг вашего кода, вам нужно только первое совпадение.
ИГРАЧ
28
var str = "test string";
str = str.substring(0,1).toUpperCase() + str.substring(1);
MaxEcho
источник
21

Оформить заказ это решение:

var stringVal = 'master';
stringVal.replace(/^./, stringVal[0].toUpperCase()); // returns Master 
Раджу Бера
источник
3
Это должен быть принятый ответ. Основное решение не должно использовать такие рамки, как подчеркивание.
Адам Макартур
3
Сохранить несколько нажатий клавиш;)stringVal.replace(/^./, stringVal[0].toUpperCase());
Альфредо Дельгадо
1
Регулярные выражения не должны использоваться там, где это не нужно. Это очень неэффективно и не делает код более лаконичным. Более того, stringVal[0]было бы undefinedпустым stringVal, и как таковая попытка доступа к свойству .toUpperCase()выкинула бы ошибку.
Przemek
20
yourString.replace(/^[a-z]/, function(m){ return m.toUpperCase() });

(Вы можете инкапсулировать его в функцию или даже добавить его в прототип String, если будете часто его использовать.)

Саймон
источник
5
Несмотря на то, что это имеет довольно много голосов, это самое медленное решение, опубликованное здесь. Я собрал небольшой тест скорости
Робин ван Баален
@RobinvanBaalen Ваша ссылка теперь не работает. Есть обновленный?
Бред
1
Регулярное выражение для этого излишне, предпочитайте более простое: str.charAt (0) .toUpperCase () + str.slice (1)
Симон
@ К сожалению, нет
Робин ван Баален
Часто, если вы хотите решить свою проблему с помощью регулярных выражений, вы сталкиваетесь с двумя проблемами.
Przemek
19

ucfirstФункция работает , если вы делаете это так.

function ucfirst(str) {
    var firstLetter = str.slice(0,1);
    return firstLetter.toUpperCase() + str.substring(1);
}

Спасибо JP за акларацию.

raphie
источник
2
хорошее название для функции! Его имя идентично эквиваленту PHP. На самом деле есть целая библиотека PHP-функций, написанных на JS; он называется PHP.js и находится на http://phpjs.org
Hussam,
11
Один лайнер:string[0].toUpperCase() + string.substring(1)
др.димитру
@TarranJones здесь пуленепробиваемый один вкладыш:(string[0] || '').toUpperCase() + string.substring(1)
dr.dimitru
@ dr.dimitru: Вместо идиоматического (string[0] || '')вы могли бы просто string.charAt(0).
Przemek
18

Вы можете сделать это в одну строку, как это

string[0].toUpperCase() + string.substring(1)
Qwerty
источник
Этот ответ был дан уже в 2009 году .
Дан Даскалеску
17
yourString.replace(/\w/, c => c.toUpperCase())

Я нашел эту функцию стрелки проще всего. Replace соответствует первой букве символа ( \w) вашей строки и преобразует ее в верхний регистр. Ничего более причудливого не нужно.

волк
источник
1
Это должен быть принятый ответ, вместо этого он является почти последним, поскольку SO продолжает присваивать устаревшие вопросы. Кстати, лучше использовать /./по двум причинам: /\w/пропустит все предыдущие не буквенные символы (поэтому @@ abc станет @@ Abc), а затем не будет работать с
нелатинскими