Преобразовать строку в заголовок с помощью JavaScript - PullRequest
477 голосов
/ 13 октября 2008

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

Ответы [ 49 ]

4 голосов
/ 30 сентября 2014

Используя решение «lewax00», я создал это простое решение, которое заставляет «w» начинаться с пробела или «w», которые инициируют слово, но не может удалить лишние промежуточные пробелы.

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

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

3 голосов
/ 06 июня 2017

Для тех из нас, кто боится регулярных выражений (смеется):

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 голосов
/ 25 октября 2018

вот еще одно решение с использованием 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 голосов
/ 18 июля 2017

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

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

Проблемы с использованием заглавных букв первой буквы каждого имени:

• Сокращения, такие как IBM, которые не допускаются для ввода, превратятся в Ibm.

• Имя McDonald превратится в Mcdonald, что неверно, то же самое относится и к MacDonald.

• Двуствольные имена, такие как Мари-Тонкс, превратятся в Мари-Тонкс.

• Такие имена, как О'Коннор, превратились бы в О'Коннор.

Для большинства из них вы могли бы написать собственные правила, чтобы справиться с этим, однако, это по-прежнему имеет проблемы с сокращениями, как и раньше, и вы получаете новую проблему:

• Если добавить правило для исправления имен с Mac, например MacDonald, то имена разрывов, например Macy, превратят его в MacY.

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

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

3 голосов
/ 11 декабря 2016

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

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;
}
3 голосов
/ 16 октября 2017

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

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

toTitleCase Function

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

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

2 голосов
/ 20 ноября 2015

Это основано на моем решении для FreeCodeCamp's Bonfire "Заглавный регистр" , который требует от вас сначала преобразовать данную строку во все строчные буквы, а затем преобразовать каждый символ, начиная с пробела, в верхний регистр.

Без использования регулярных выражений:

function titleCase(str) {
 return str.toLowerCase().split(' ').map(function(val) { return val.replace(val[0], val[0].toUpperCase()); }).join(' ');
}
2 голосов
/ 02 мая 2016

Моя простая и легкая версия проблемы:

    function titlecase(str){
    var arr=[];  
    var str1=str.split(' ');
    for (var i = 0; i < str1.length; i++) {
    var upper= str1[i].charAt(0).toUpperCase()+ str1[i].substr(1);
    arr.push(upper);
     };
      return arr.join(' ');
    }
    titlecase('my name is suryatapa roy');
2 голосов
/ 30 сентября 2017

Сначала преобразуйте string в массив с помощью , разделив на пробелы:

var words = str.split(' ');

Затем используйте array.map , чтобы создать новый массив, содержащий слова с заглавными буквами.

var capitalized = words.map(function(word) {
    return word.charAt(0).toUpperCase() + word.substring(1, word.length);
});

Затем объединить новый массив с пробелами:

capitalized.join(" ");

function titleCase(str) {
  str = str.toLowerCase(); //ensure the HeLlo will become Hello at the end
  var words = str.split(" ");

  var capitalized = words.map(function(word) {
    return word.charAt(0).toUpperCase() + word.substring(1, word.length);
  });
  return capitalized.join(" ");
}

console.log(titleCase("I'm a little tea pot"));

Примечание:

Это, конечно, имеет недостаток. Это будет использовать только первую букву каждого слова. Словом это означает, что каждая строка, разделенная моими пробелами, обрабатывается как 1 слово.

Предположительно у вас есть:

str = "I'm a little/small tea pot";

Это даст

I'm A Little / small Чайник

по сравнению с ожидаемым

Я маленький / маленький чайник

В этом случае, используя Regex и .replace добьетесь цели:

с ES6:

const capitalize = str => str.length
  ? str[0].toUpperCase() +
    str.slice(1).toLowerCase()
  : '';

const escape = str => str.replace(/./g, c => `\\${c}`);
const titleCase = (sentence, seps = ' _-/') => {
  let wordPattern = new RegExp(`[^${escape(seps)}]+`, 'g');
  
  return sentence.replace(wordPattern, capitalize);
};
console.log( titleCase("I'm a little/small tea pot.") );

или без ES6 :

function capitalize(str) {
  return str.charAt(0).toUpperCase() + str.substring(1, str.length).toLowerCase();
}

function titleCase(str) {
  return str.replace(/[^\ \/\-\_]+/g, capitalize);
}

console.log(titleCase("hello/hi world"));
1 голос
/ 09 сентября 2015

Более простая, более производительная версия с простым кэшированием.

  var TITLE_CASE_LOWER_MAP = {
    'a': 1, 'an': 1, 'and': 1, 'as': 1, 'at': 1, 'but': 1, 'by': 1, 'en':1, 'with': 1,
    'for': 1, 'if': 1, 'in': 1, 'of': 1, 'on': 1, 'the': 1, 'to': 1, 'via': 1
  };

  // LEAK/CACHE TODO: evaluate using LRU.
  var TITLE_CASE_CACHE = new Object();

  toTitleCase: function (title) {
    if (!title) return null;

    var result = TITLE_CASE_CACHE[title];
    if (result) {
      return result;
    }

    result = "";
    var split = title.toLowerCase().split(" ");
    for (var i=0; i < split.length; i++) {

      if (i > 0) {
        result += " ";
      }

      var word = split[i];
      if (i == 0 || TITLE_CASE_LOWER_MAP[word] != 1) {
        word = word.substr(0,1).toUpperCase() + word.substr(1);
      }

      result += word;
    }

    TITLE_CASE_CACHE[title] = result;

    return result;
  },
...