Как сделать первую букву каждого слова заглавной? (регулярные выражения JS)

134
13 января 2021, 10:50

У меня есть код, который исправляет первую букву каждого слова в инпуте на заглавную букву, очень полезно для инпутов имен. Так вот данный код исправляет только англоязычные имена, как исправить регулярное выражение чтобы он исправлял и русские имена.

function capitalize(input) { 
  input.value = input.value.replace(/\b[a-z](?=[a-z]{2})/gi, function(letter) { 
    return letter.toUpperCase(); 
  }); 
}
<label><span class="label_red">*</span> Имя, Фамилия:</label> 
<input type="text" name="name" maxlength="80" placeholder="Иван Иванов" required onkeyup="capitalize(this);">

Я пробовал написать /\b[а-я](?=[а-я]{2})/gi но это не работает. Если ввести имя anna ivanova оно исправится на Anna Ivanova. Как сделать тоже самое для кириллицы и добавить регулярное выражение для русских имен. анна иванова => Анна Иванова. Спасибо за помощь!

Answer 1

Новое слово... это либо начало строки ^, либо буква после пробела, так? Ну вот пример:

let str = 'you know nothing jon snow';  
   // Просто пробел ↓ хотя можно было явно записать \s ('s', от слова 'space') 
str = str.replace(/( |^)[а-яёa-z]/g, function(x){ return x.toUpperCase(); }  ); 
 
console.log( str );

И в вашем случае:

function capitalize(input) { 
  input.value = input.value.replace(/( |^)[а-яёa-z]/g, function(u){ return u.toUpperCase(); }  ); 
} 
 
document.getElementById('bubu').addEventListener('input', function(){ 
  capitalize(this); 
});
<label><span class="label_red">*</span> Имя, Фамилия:</label> 
<input id="bubu" type="text" name="name" maxlength="80" placeholder="Иван Иванов" required>

P.s. хотя можно было без регулярок, разбить строчку на str.split(' ') элементы массива... в каждом элементе сделать первую букву заглавной (уже независимо от языка), а потом собрать строчку обратно.

P.P.s input срабатывает только в случае изменения введенного текста, тогда как keyup запускается после каждой нажатой кнопки, даже CTRL, SHIFT и т.п. Поэтому можно использовать первое, чтобы лишний раз не запускать функцию.

Answer 2

Если поддерживается достаточно новый стандарт джаваскрипта, то можно так:

function capittalize(s) { 
  return s.toLowerCase().replace(/(?<!\p{Lowercase})\p{Lowercase}/gu, ch => ch.toUpperCase()) 
} 
 
document.querySelector("input").addEventListener('input', e => { 
  document.querySelector("output").textContent = capittalize(e.target.value) 
}) 
 
document.querySelector("input").dispatchEvent(new Event('input'))
<input value="ёЖиК ЛеснИчий"> 
<output></output>

Answer 3

Я бы не использовал строго указанные диапазоны символов, т.к. они строго привязаны к используемому/возможному набору символов. Вместо этого, как уже говорил @OPTIMUSPRIME, можно ориентироваться на другие ориентиры:

String.prototype.capitalize = function() {
    return this.replace(/(?:^|\s)\S/g, function(a) {
            return a.toUpperCase();
        });
};
'your string'.capitalize(); // -> 'Your String'
'бабушка курит трубку'.capitalize();  // -> 'Бабушка Курит Трубку'
'località àtilacol'.capitalize()      // -> 'Località Àtilacol'

Преимущество этого подхода - в его универсальности, т.е. он будет работать вне зависимости от используемых символов в строке.

Для нормализации строки, как предлагает автор оригинального ответа, можно дополнить:

String.prototype.capitalize = function(lower) {
    return (lower ? this.toLowerCase() : this)
        .replace(/(?:^|\s)\S/g, function(a) { 
            return a.toUpperCase();
        });
};
'javaSCrIPT'.capitalize();      // -> 'JavaSCrIPT'
'javaSCrIPT'.capitalize(true);  // -> 'Javascript'

Взято отсюда.

Answer 4

Можно передавать callback в качестве параметра для replace

var input = "Example string пример строки" 
 
console.log( 
  input.replace(/[a-zа-я]+/gi, (match) => match[0].toUpperCase()+match.substr(1)) 
)

READ ALSO
Объединить в один массив

Объединить в один массив

Как объединить все вложенные массивы в один и если будут повторяющиеся элементы, то убрать ихНапример 12,13 буду встречаться в итоговом едином...

114
Фильтр блоков по значениям нескольких выпадающих списков

Фильтр блоков по значениям нескольких выпадающих списков

Есть выпадающие списки, которые определяют параметры фильтрации:

110