Convert string to title case with JavaScript

后端 未结 30 2784
夕颜
夕颜 2020-11-21 06:40

Is there a simple way to convert a string to title case? E.g. john smith becomes John Smith. I\'m not looking for something complicated like John R

相关标签:
30条回答
  • 2020-11-21 07:28

    Try this

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

    Example

    var str = 'john smith';
    str.toProperCase();
    
    0 讨论(0)
  • 2020-11-21 07:29

    I think the simplest is using css.

    function format_str(str) {
        str = str.toLowerCase();
        return '<span style="text-transform: capitalize">'+ str +'</span>';
    }
    
    0 讨论(0)
  • 2020-11-21 07:29

    I wanted to add my own answer as I needed a robust toTitleCase function that takes into account grammar rules listed here (Google recommended article). There are various rules that depend on the length of the input string. Below is the function + unit tests.

    The function also consolidates whitespace and removes special characters (modify regex for your needs)

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

    Unit Tests to Ensure Correctness

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

    Please note that I am removing quite a bit of special characters from the strings provided. You will need to tweak the regex to address the requirements of your project.

    0 讨论(0)
  • 2020-11-21 07:30

    Here is my function that is taking care of accented characters (important for french !) and that can switch on/off the handling of lowers exceptions. Hope that helps.

    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;
    }
    
    0 讨论(0)
  • 2020-11-21 07:31
    var toMatch = "john w. smith";
    var result = toMatch.replace(/(\w)(\w*)/g, function (_, i, r) {
          return i.toUpperCase() + (r != null ? r : "");
        }
    )
    

    Seems to work... Tested with the above, "the quick-brown, fox? /jumps/ ^over^ the ¡lazy! dog..." and "C:/program files/some vendor/their 2nd application/a file1.txt".

    If you want 2Nd instead of 2nd, you can change to /([a-z])(\w*)/g.

    The first form can be simplified as:

    function toTitleCase(toTransform) {
      return toTransform.replace(/\b([a-z])/g, function (_, initial) {
          return initial.toUpperCase();
      });
    }
    
    0 讨论(0)
  • 2020-11-21 07:33

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

    0 讨论(0)
提交回复
热议问题