Есть ли простой способ конвертировать строку в заголовок? Например john smith
становится John Smith
. Я не ищу чего-то сложного, такого как решение Джона Резига , просто (надеюсь) какой-то одно- или двухслойный.
Есть ли простой способ конвертировать строку в заголовок? Например john smith
становится John Smith
. Я не ищу чего-то сложного, такого как решение Джона Резига , просто (надеюсь) какой-то одно- или двухслойный.
Ответы:
Попробуй это:
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*
используется, а не \w+
или, \w*
например? Я не знаю, почему вы захотите включить что-нибудь, кроме пробелов, и поэтому измените Джим-Боб на Джим-боб .
\w\S*
также вызвал Jim-bob
проблему с нашей стороны. Использование \w*
решило это.
/([^\W_]+[^\s-]*) */g
решает Jim-Bob
проблему, т.е.:jim-bob
-->
Jim-Bob
jim-bob
-->
Jim-Bob
это ваше желание, вы, вероятно, должны сделать /\b\w+/g
. Пример:str.replace(/\b\w+/g,function(s){return s.charAt(0).toUpperCase() + s.substr(1).toLowerCase();});
\w\S*
используется вместо \w+
или \w*
так, чтобы слова вроде Don't
не изменялись Don'T
, но, как указывали другие, \w\S*
вызывает проблемы с переносами слов.
Немного более элегантный способ, адаптирующий функцию Грега Дина:
String.prototype.toProperCase = function () {
return this.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();});
};
Назовите это как:
"pascal".toProperCase();
Jo-Ann Smith
, этот код преобразует его в Jo-ann Smith
(обратите внимание на нижний регистр a
в Ann
).
Попробуйте применить CSS-стиль для преобразования текста к элементам управления.
например: (text-transform: capitalize);
Используйте подход JS только тогда, когда это абсолютно необходимо.
Вот моя версия, ИМО, это легко понять и элегантно.
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()
. Имена, такие как «McDonald» или аббревиатуры, такие как «ASAP», должны сохранять заглавные буквы. Если кто-то фактически передал строку типа «heLLO», приложение не должно предполагать, что заглавные буквы неверны.
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
будет один символ.
Вот моя функция, которая преобразует в регистр заглавия, но также сохраняет определенные аббревиатуры в верхнем регистре и второстепенные слова в нижнем регистре:
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:"
/\w\S*/g
на /([^\W_]+[^\s-]*) */g
на @ awashburn замечании выше для решения этой проблемы .
/\b\w+/g
, который я считаю более быстрым?
/([^\W_]+[^\s-]*) */g
до /\b\w+/g
пер @ комментарий Майкла; пожалуйста, прокомментируйте, если вы найдете случай, когда необходимо более сложное регулярное выражение.
/\b[\w-\']+/g
, чтобы разрешить переносить слова и апостроф в словах.
Я предпочитаю следующее над другими ответами. Он соответствует только первой букве каждого слова и заглавными буквами. Более простой код, легче для чтения и меньше байтов. Он сохраняет существующие заглавные буквы для предотвращения искажений аббревиатур. Однако вы всегда 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() });
}
Пример:
const titleCase = (str) => str.replace(/\b\S/g, t => t.toUpperCase());
NoT qUiITe
.
toLowerCase
. Просто знайте, что это нарушит аббревиатуры. an HTML document
: An HTML Document
vsAn Html Document
toLowerCase
) является более гибким / полезным, чем тот, который предполагает намерения разработчиков. Этот метод также отражает функциональность аналогичных встроенных методов других языков, таких как PHP ( ucwords
) и Golang ( strings.Title
). .NET ( TextInfo.ToTitleCase
) интересно работает в смешанном регистре, но также оставит полностью заглавные строки без изменений.
Без использования регулярных выражений только для справки:
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;})
Опять же, это работает только для заглавных букв первой буквы строки, но в случае, если это то, что вам нужно, моя конструкция работает.
'$1'.toUpperCase()
, кажется, что заглавные буквы не были сделаны к моменту назначения значения. 'string'.replace(/^(.){1}/,function(match) { return match.toUpperCase(); })
Вы можете сразу 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()})}})
=>
, что это встроенная функция стрелок (ES6), ссылка переходит к документам Mozillla на них, которая также предоставляет таблицу поддержки.
На всякий случай, если вас волнуют эти слова-наполнители, вы всегда можете просто сказать функции, что не использовать заглавные буквы.
/**
* @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;
});
};
glue ='de|da|del|dos|do|das|des|la|della|delli'.split('|');
and another thing
становится and Another Thing
. Просто нужен элегантный способ всегда использовать первое слово с большой буквы.
Если регулярное выражение, используемое в приведенных выше решениях, вводит вас в заблуждение, попробуйте этот код:
function titleCase(str) {
return str.split(' ').map(function(val){
return val.charAt(0).toUpperCase() + val.substr(1).toLowerCase();
}).join(' ');
}
split
действительно конвертирует его в массив, вы просто не видите это так очевидно, потому что map
означает, что вам не нужно использовать []
нотацию
Я сделал эту функцию, которая может обрабатывать фамилии (так что это не случай названия), такие как «Макдональд» или «Макдональд» или «О'Тул» или «Д'Орацио». Однако он не обрабатывает немецкие или голландские имена с "van" или "von", которые часто пишутся в нижнем регистре ... Я считаю, что "de" тоже часто в нижнем регистре, например, "Robert de Niro". Эти вопросы все еще должны быть решены.
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
проблему, положив туда негативную \b((m)(a?c))?(\w)
\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 : "");
}
)
Кажется, работает ... Протестировано с вышеупомянутым, "быстрый коричневый, лиса? / Прыжки / ^ над ^ ленивый! Собака ..." и "C: / программные файлы / какой-то поставщик / их второе приложение / а file1.txt».
Если вы хотите 2-й вместо 2-го, вы можете изменить на /([a-z])(\w*)/g
.
Первая форма может быть упрощена как:
function toTitleCase(toTransform) {
return toTransform.replace(/\b([a-z])/g, function (_, initial) {
return initial.toUpperCase();
});
}
Попробуй это
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();
Если вы можете использовать сторонние библиотеки в своем коде, тогда у 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'
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()
если вы все еще хотите эту первую букву.
str
- одиночный персонаж
.charAt(0).toUpperCase()
.
Большинство этих ответов, похоже, игнорируют возможность использования метасимвола границы слова (\ b). Более короткая версия ответа Грега Дина, использующего его:
function toTitleCase(str)
{
return str.replace(/\b\w/g, function (txt) { return txt.toUpperCase(); });
}
Работает для дефисных имен, таких как Джим-Боб тоже.
Я думаю, что самым простым является использование CSS.
function format_str(str) {
str = str.toLowerCase();
return '<span style="text-transform: capitalize">'+ str +'</span>';
}
Используйте /\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 unshine ( y ellow)" ⇒ " S unshine ( y ellow)"
Я хотел добавить свой собственный ответ, так как мне нужна надежная 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');
});
});
Обратите внимание, что я удаляю довольно много специальных символов из предоставленных строк. Вам нужно будет настроить регулярное выражение в соответствии с требованиями вашего проекта.
"john f. kennedy".replace(/\b\S/g, t => t.toUpperCase())
o'henry
, но делает странные вещи с horse's mouth
.
"john f. kennEdy".toLowerCase().replace(/\b\S/g, t => t.toUpperCase())
лучше 🤔
\b
и \S
являются специальными классами символов, обозначающими «границу слова» и «один непробельный символ. Таким образом, регулярное выражение соответствует каждому отдельному символу, следующему за границей слова, и использует этот знак с большой буквы, применяя данную функцию стрелки.
Используя решение «lewax00», я создал это простое решение, которое заставляет «w» начинаться с пробела или «w», которые инициируют слово, но не может удалить лишние промежуточные пробелы.
"SOFÍA vergara".toLowerCase().replace(/\b(\s\w|^\w)/g, function (txt) { return txt.toUpperCase(); });
Результат "София Вергара".
Вот моя функция, которая заботится об акцентированных символах (важно для французского!) И которая может включать / выключать обработку исключений более низкого уровня. Надеюсь, это поможет.
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;
}
У нас здесь, в офисе, было обсуждение, и мы думаем, что попытка автоматически исправить то, как люди вводят имена в том виде, в котором вы хотите, чтобы это происходило, чревата возможными проблемами.
Мы придумали несколько случаев, когда разные типы автокапитализации распадаются, и это только для английских имен, каждый язык имеет свои сложности.
Проблемы с использованием заглавных букв первой буквы каждого имени:
• Сокращения, такие как IBM, не разрешенные для ввода, превратятся в Ibm.
• Имя McDonald превратится в Mcdonald, что неверно, то же самое относится и к MacDonald.
• Двуствольные имена, такие как «Мари-Тонкс», превратятся в «Мари-Тонкс».
• Имена как О'Коннор превратятся в О'Коннор.
Для большинства из них вы могли бы написать собственные правила, чтобы справиться с этим, однако, это по-прежнему имеет проблемы с сокращениями, как и раньше, и вы получаете новую проблему:
• Добавление правила для исправления имен с Mac, таких как MacDonald, приведет к тому, что имена разрывов, такие как Macy, превратят его в MacY.
Единственное решение, которое мы придумали, которое никогда не бывает неправильным, состоит в том, чтобы использовать каждую букву с заглавной буквы, которая является методом грубой силы, который, по-видимому, также использует DBS.
Так что, если вы хотите автоматизировать процесс, это так же невозможно, как без словаря каждого отдельного имени и слова, и как оно должно быть прописным. Если у вас нет правила, которое охватывает все, не используйте его как оно будет просто раздражать ваших пользователей и предлагать людям, которые хотят правильно ввести свои имена, пойти куда-нибудь еще.
Вот еще одно решение с использованием 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;}
Для тех из нас, кто боится регулярных выражений (смеется):
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(" ");
}
Мое однострочное решение:
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
Удивило, что никто не упомянул об использовании параметра rest. Вот простой вкладыш, который использует параметры ES6 Rest.
let str="john smith"
str=str.split(" ").map(([firstChar,...rest])=>firstChar.toUpperCase()+rest.join("").toLowerCase()).join(" ")
console.log(str)
Это основано на моем решении для Bonfire FreeCodeCamp "Заголовок дела" , которое требует, чтобы вы сначала преобразовали данную строку во все строчные буквы, а затем преобразовали каждый символ, начиная с пробела, в верхний регистр.
Без использования регулярных выражений:
function titleCase(str) {
return str.toLowerCase().split(' ').map(function(val) { return val.replace(val[0], val[0].toUpperCase()); }).join(' ');
}