Tekenreeks converteren naar hoofdlettergebruik met JavaScript

Is er een eenvoudige manier om een ​​string om te zetten in Titel Case? bijv. John Smith wordt John Smith. Ik ben niet op zoek naar iets ingewikkelds zoals John Resigs oplossing, maar (hopelijk ) een soort one- of two-liner.


Antwoord 1, autoriteit 100%

Probeer dit:

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>

Antwoord 2, autoriteit 26%

Probeer de CSS-stijl text-transform toe te passen op uw bedieningselementen.

bijv.: (text-transform: capitalize);


Antwoord 3, autoriteit 25%

Een iets elegantere manier, waarbij de functie van Greg Dean wordt aangepast:

String.prototype.toProperCase = function () {
    return this.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();});
};

Noem het als:

"pascal".toProperCase();

Antwoord 4, autoriteit 17%

Hier is mijn versie, IMO, het is gemakkelijk te begrijpen en ook elegant.

var str = "foo bar baz"
console.log(
str.split(' ')
   .map(w => w[0].toUpperCase() + w.substr(1).toLowerCase())
   .join(' ')
)
// returns "Foo Bar Baz"

Antwoord 5, autoriteit 13%

Hier is mijn functie die converteert naar hoofdletters in de titel, maar ook gedefinieerde acroniemen behoudt als hoofdletters en kleine woorden als kleine letters:

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

Bijvoorbeeld:

"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:"

Antwoord 6, autoriteit 6%

Ik geef de voorkeur aan het volgende boven de andere antwoorden. Het komt alleen overeen met de eerste letter van elk woord en maakt er een hoofdletter van. Eenvoudigere code, gemakkelijker te lezen en minder bytes. Het behoudt bestaande hoofdletters om vervormende acroniemen te voorkomen. Je kunt echter altijd eerst toLowerCase() aanroepen op je string.

function title(str) {
  return str.replace(/(^|\s)\S/g, function(t) { return t.toUpperCase() });
}

Je kunt dit toevoegen aan je string-prototype waarmee je als volgt 'my string'.toTitle() kunt gebruiken:

String.prototype.toTitle = function() {
  return this.replace(/(^|\s)\S/g, function(t) { return t.toUpperCase() });
}

Voorbeeld:


Antwoord 7, autoriteit 3%

U kunt de tekenreeks onmiddellijk toLowerCase en dan gewoon toUpperCase de eerste letter van elk woord. Wordt een heel eenvoudige 1-liner:

function titleCase(str) {
  return str.toLowerCase().replace(/\b(\w)/g, s => s.toUpperCase());
}
console.log(titleCase('iron man'));
console.log(titleCase('iNcrEdible hulK'));

Antwoord 8, autoriteit 3%

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

Antwoord 9, autoriteit 2%

Zonder regex alleen ter referentie te gebruiken:

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()
)

Antwoord 10, autoriteit 2%

Verrast om te zien dat niemand het gebruik van de rustparameter noemde. Hier is een eenvoudige oneliner die gebruikmaakt van ES6 Rest-parameters.

let str="john smith"
str=str.split(" ").map(([firstChar,...rest])=>firstChar.toUpperCase()+rest.join("").toLowerCase()).join(" ")
console.log(str)

Antwoord 11, autoriteit 2%

Voor het geval je je zorgen maakt over die opvulwoorden, kun je de functie altijd vertellen wat ze niet met een hoofdletter moeten schrijven.

/**
 * @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();
    });
};

Ik hoop dat dit je helpt.

bewerken

Als je voorloopwoorden wilt gebruiken, kun je dit bijhouden met nog een variabele:

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

Antwoord 12, autoriteit 2%

Als de regex die in de bovenstaande oplossingen wordt gebruikt u in de war brengt, probeer dan deze code:

function titleCase(str) {
  return str.split(' ').map(function(val){ 
    return val.charAt(0).toUpperCase() + val.substr(1).toLowerCase();
  }).join(' ');
}

Antwoord 13, autoriteit 2%

Benchmark

TL;DR

De winnaar van deze benchmark is de gewone oude for loop:

function titleize(str) {
    let upper = true
    let newStr = ""
    for (let i = 0, l = str.length; i < l; i++) {
        // Note that you can also check for all kinds of spaces  with
        // str[i].match(/\s/)
        if (str[i] == " ") {
            upper = true
            newStr += str[i]
            continue
        }
        newStr += upper ? str[i].toUpperCase() : str[i].toLowerCase()
        upper = false
    }
    return newStr
}
// NOTE: you could beat that using charcode and string builder I guess.

Werkelijke benchmark

Ik heb de meest populaire en duidelijke antwoorden genomen en daarmee een benchmark gemaakt.

Dit is het resultaat op mijn MacBook pro:

voer hier de afbeeldingsbeschrijving in

En voor de volledigheid, hier zijn de gebruikte functies:

str = "the QUICK BrOWn Fox jUMPS oVeR the LAzy doG";
function regex(str) {
  return str.replace(
    /\w\S*/g,
    function(txt) {
      return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
    }
  );
}
function split(str) {
  return str.
    split(' ').
    map(w => w[0].toUpperCase() + w.substr(1).toLowerCase()).
    join(' ');
}
function complete(str) {
  var i, j, str, lowers, uppers;
  str = str.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;
}
function firstLetterOnly(str) {
  return str.replace(/\b(\S)/g, function(t) { return t.toUpperCase(); });
}
function forLoop(str) {
  let upper = true;
  let newStr = "";
  for (let i = 0, l = str.length; i < l; i++) {
    if (str[i] == " ") {
      upper = true;
        newStr += " ";
      continue;
    }
    newStr += upper ? str[i].toUpperCase() : str[i].toLowerCase();
    upper = false;
  }
  return newStr;
}

Merk op dat ik het prototype opzettelijk niet heb veranderd, omdat ik het een erg slechte gewoonte vind en ik denk niet dat we een dergelijke praktijk in onze antwoorden moeten promoten. Dit is alleen oké voor kleine codebases als jij de enige bent die eraan werkt.

Als je een andere manier wilt toevoegen om dit aan deze benchmark te doen, plaats dan een link naar het antwoord!


Antwoord 14

Ik heb deze functie gemaakt die achternamen kan verwerken (dus geen hoofdletters) zoals “McDonald” of “MacDonald” of “O’Toole” of “D’Orazio”. Het behandelt echter geen Duitse of Nederlandse namen met “van” of “von” die vaak in kleine letters staan… Ik geloof dat “de” ook vaak kleine letters is, zoals “Robert de Niro”. Deze zouden nog moeten worden aangepakt.

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

Antwoord 15

Als je bibliotheken van derden in je code kunt gebruiken, heeft lodash een hulpfunctie voor ons.

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'

Antwoord 16

ES 6

str.split(' ')
   .map(s => s.slice(0, 1).toUpperCase() + s.slice(1).toLowerCase())
   .join(' ')

anders

str.split(' ').map(function (s) {
    return s.slice(0, 1).toUpperCase() + s.slice(1).toLowerCase();
}).join(' ')

Antwoord 17

var toMatch = "john w. smith";
var result = toMatch.replace(/(\w)(\w*)/g, function (_, i, r) {
      return i.toUpperCase() + (r != null ? r : "");
    }
)

Het lijkt te werken…
Getest met het bovenstaande, “the quick-brown, fox? /jumps/ ^over^ the ?lazy! dog…” en “C:/program files/some vendor/the their 2nd application/a file1.txt”.

Als je de 2e wilt in plaats van de 2e, kun je veranderen in /([a-z])(\w*)/g.

Het eerste formulier kan worden vereenvoudigd als:

function toTitleCase(toTransform) {
  return toTransform.replace(/\b([a-z])/g, function (_, initial) {
      return initial.toUpperCase();
  });
}

Antwoord 18

De meeste van deze antwoorden lijken de mogelijkheid te negeren om het woord grensmetateken (\b) te gebruiken. Een kortere versie van het antwoord van Greg Dean die het gebruikt:

function toTitleCase(str)
{
    return str.replace(/\b\w/g, function (txt) { return txt.toUpperCase(); });
}

Werkt ook voor namen met koppeltekens zoals Jim-Bob.


Antwoord 19

Probeer dit, kortste weg:

str.replace(/(^[a-z])|(\s+[a-z])/g, txt => txt.toUpperCase());

Antwoord 20

Converteer eerst uw string naar een array door splitsen door spaties:

var words = str.split(' ');

Gebruik vervolgens array.map om een ​​nieuwe array te maken die de woorden met een hoofdletter bevat.

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

Vervolgens doe nieuwe array met spaties:

capitalized.join(" ");

Antwoord 21

Probeer dit

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

Voorbeeld

var str = 'john smith';
str.toProperCase();

Antwoord 22

Ik wilde mijn eigen antwoord toevoegen omdat ik een robuuste toTitleCase-functie nodig had die rekening houdt met grammaticaregels hier vermeld (artikel aanbevolen door Google). Er zijn verschillende regels die afhankelijk zijn van de lengte van de invoerreeks. Hieronder vindt u de functie + eenheidstests.

De functie consolideert ook witruimte en verwijdert speciale tekens (wijzig regex voor uw behoeften)

toTitleCase-functie

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

Eenheidstests om de juistheid te garanderen

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

Houd er rekening mee dat ik nogal wat speciale tekens uit de verstrekte tekenreeksen verwijder. U moet de regex aanpassen om aan de vereisten van uw project te voldoen.


Antwoord 23

Ik denk dat het gebruik van css het eenvoudigst is.

function format_str(str) {
    str = str.toLowerCase();
    return '<span style="text-transform: capitalize">'+ str +'</span>';
}

Antwoord 24

"john f. kennedy".replace(/\b\S/g, t => t.toUpperCase())

Antwoord 25

Hier is een heel eenvoudig & beknopte ES6-functie om dit te doen:

const titleCase = (str) => {
  return str.replace(/\w\S*/g, (t) => { return t.charAt(0).toUpperCase() + t.substr(1).toLowerCase() });
}
export default titleCase;

Werkt goed opgenomen in een map utilities en wordt als volgt gebruikt:

import titleCase from './utilities/titleCase.js';
const string = 'my title & string';
console.log(titleCase(string)); //-> 'My Title & String'

Antwoord 26

Gebruik /\S+/g om diakritische tekens te ondersteunen:

function toTitleCase(str) {
  return str.replace(/\S+/g, str => str.charAt(0).toUpperCase() + str.substr(1).toLowerCase());
}
console.log(toTitleCase("a city named orebro")); // A City Named Orebro

Antwoord 27

Met de “lewax00”-oplossing heb ik deze eenvoudige oplossing gemaakt die forceert naar “w” beginnend met spatie of “w” die het woord initiëren, maar niet in staat is om de extra tussenliggende spaties te verwijderen.

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

Antwoord 28

Hier is mijn functie die zorgt voor karakters met accenten (belangrijk voor frans !) en die de afhandeling van lagere uitzonderingen kan in-/uitschakelen. Ik hoop dat dat helpt.

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', 'A', 'Au', 'Aux', 'Par', 'Pour', 'Dans', 'Sur', 'Et', 'Comme', 'Mais', 'Ou', 'Ou', '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;
}

Antwoord 29

We hebben hier op kantoor een discussie gevoerd en we denken dat het proberen om de manier waarop mensen namen automatisch invoeren op de huidige manier te corrigeren zoals u dat wilt, veel problemen kan opleveren.

We hebben verschillende gevallen bedacht waarin verschillende soorten automatisch hoofdlettergebruik uit elkaar vallen en deze zijn alleen voor Engelse namen, elke taal heeft zijn eigen complexiteit.

Problemen met hoofdletters van de eerste letter van elke naam:

Acroniemen zoals IBM mogen niet worden ingevoerd, zouden veranderen in IBM.

De naam McDonald zou in Mcdonald veranderen, wat niet klopt, hetzelfde geldt ook voor MacDonald.

Dubbelloops namen zoals Marie-Tonks zouden veranderen in Marie-tonks.

Namen als O Connor zouden in O connor veranderen.

Voor de meeste hiervan zou je aangepaste regels kunnen schrijven om ermee om te gaan, maar dit heeft nog steeds problemen met acroniemen zoals voorheen en je krijgt een nieuw probleem:

Door een regel toe te voegen om namen met Mac zoals MacDonald te corrigeren, zouden de namen als Macy worden afgebroken en er MacY van worden gemaakt.

De enige oplossing die we hebben bedacht die nooit onjuist is, is om elke letter met een hoofdletter te schrijven, wat een brute force-methode is die de DBS ook lijkt te gebruiken.

Dus als je het proces wilt automatiseren, is het zo goed als onmogelijk om te doen zonder een woordenboek van elke naam en elk woord en hoe het met hoofdletters moet worden geschreven, Als je geen regel hebt die alles dekt, gebruik het niet, want het zal uw gebruikers alleen maar irriteren en mensen die hun naam correct willen invoeren, ertoe aanzetten ergens anders heen te gaan.


Antwoord 30

hier is een andere oplossing die css gebruikt (en javascript, als de tekst die u wilt transformeren in hoofdletters is):

html

<span id='text'>JOHN SMITH</span>

js

var str = document.getElementById('text').innerHtml;
var return_text = str.toLowerCase();

css

#text{text-transform:capitalize;}

LEAVE A REPLY

Please enter your comment!
Please enter your name here

4 × 1 =

Other episodes