Konvertieren Sie die Zeichenfolge mit JavaScript in Groß- und Kleinschreibung


549

Gibt es eine einfache Möglichkeit, eine Zeichenfolge in Groß- und Kleinschreibung umzuwandeln? ZB john smithwird John Smith. Ich suche nicht nach etwas Kompliziertem wie John Resigs Lösung , sondern (hoffentlich) nach einer Art Ein- oder Zweiliner.


Es gibt verschiedene Methoden. Haben wir einige Leistungsstatistiken?
theAnubhav

Bitte überprüfen Sie diese kurze Antwort stackoverflow.com/a/57689168/10373693 Ich hoffe, dass dies die Antwort ist, nach der Sie suchen.
Abhishek Kumar

Antworten:


740

Versuche dies:

    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>


14
Könnte jemand bitte erklären, warum \w\S*anstelle von \w+oder \w*zum Beispiel verwendet wird? Ich weiß nicht, warum Sie etwas anderes als Leerzeichen einfügen und daher Jim-Bob in Jim-Bob ändern möchten .
Martinczerwi

5
@martinCzerwi das hat \w\S*auch das Jim-bobProblem auf unserer Seite verursacht. Mit \w*gelöst.
Bouke

14
/([^\W_]+[^\s-]*) */glöst das Jim-BobProblem, dh:jim-bob --> Jim-Bob
recursion.ninja

15
Wenn das jim-bob --> Jim-Bobdein Wunsch ist, solltest du es wahrscheinlich tun /\b\w+/g. Beispiel:str.replace(/\b\w+/g,function(s){return s.charAt(0).toUpperCase() + s.substr(1).toLowerCase();});
Vol7ron

3
\w\S*wird anstelle von \w+oder verwendet, \w*damit Wörter wie Don'tnicht geändert werden Don'T, aber wie andere darauf hingewiesen haben, \w\S*verursacht dies Probleme mit Wörtern mit Bindestrich.
DoubleDown

198

Eine etwas elegantere Art, Greg Deans Funktion anzupassen:

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

Nennen Sie es wie:

"pascal".toProperCase();

3
Denken Sie daran, wenn Sie einen Benutzer mit einem Bindestrich im Namen haben und Jo-Ann Smithdieser eingibt, konvertiert dieser Code ihn in Jo-ann Smith(beachten Sie die Kleinbuchstaben ain Ann).
dbau

18
@daniellmb Warum sollte er den String-Prototyp nicht ändern? Ich denke, es ist eine gute Lösung. Denken Sie an Ruby Open-Klassen. Es ist absolut gültig, Funktionen zu vorhandenen Klassen hinzuzufügen, und es wird allgemein akzeptiert.
Marco-Fiset

97
@ marco-fiset Weil es nicht gut mit anderen spielt! Schlechte Dinge passieren, wenn Sie zwei Bibliotheken haben, die beide versuchen, native JavaScript-Objekte mit inkompatiblen Änderungen zu ändern. Stellen Sie sich vor, wenn jQuery und Google Maps diesem Entwurfsmuster folgen, können Sie nicht beide auf derselben Seite haben.
Daniellmb

5
@daniellmb Ein ausgezeichneter Punkt. Das Präfixieren des Methodennamens sollte dies vermeiden, da die Methode nicht aufzählbar ist.
Mikemaccana

60
Ich habe das Gefühl, dass die Anweisung "Native JavaScript-Objekte nicht ändern" genauso lautet wie "Niemals goto verwenden" oder "eval is evil". Es gibt viele Fälle, in denen es in Ordnung ist. Wenn Sie die vollständige Kontrolle über Ihr Projekt haben und natürlich nicht vorhaben, es als Bibliothek freizugeben, sehe ich keine Probleme mit dieser Methode.
FoxMulder900

175

Versuchen Sie, die anzuwenden text-trans CSS Stil , um Ihre Kontrollen.

z.B: (text-transform: capitalize);

Verwenden Sie einen JS-Ansatz nur, wenn dies unbedingt erforderlich ist.


36
-1. Dieses CSS funktioniert, funktioniert aber nicht so, wie es die meisten Leute erwarten, denn wenn der Text als Großbuchstaben beginnt, gibt es keine Auswirkung. webmasterworld.com/forum83/7506.htm
whitneyland

2
@Akshar: Eine Kleinbuchstabenregel wird durch eine Titelbuchstabenregel ersetzt. Da CSS den Quellinhalt nicht ändert, wird die Kleinbuchstabenregel entfernt (der Quellinhalt bleibt in Großbuchstaben), und dann wird die Titelbuchstabenregel angewendet (es wird nichts unternommen).
Dokkaebi

42
JS wird außerhalb von Browsern verwendet.
Mikemaccana

4
Die Frage war: "Gibt es eine einfache Möglichkeit, eine Zeichenfolge in Groß- und Kleinschreibung umzuwandeln?" . Diese Antwort konvertiert keine Zeichenfolge. Dies ist ein Stil, der auf eine Zeichenfolge angewendet wird.
kingPuppy

Wenn Sie möchten, dass die Daten in Ihrer Datenbank sauber sind, damit sie beim Übergeben an Dienste von Drittanbietern oder beim Exportieren in CSV sauber verwendet werden können, ist CSS keine Option. CSS ist für Kosmetika gedacht, und obwohl es im Laufe der Jahre stark gewachsen ist und Sie es zur Lösung dieser Art von Problemen verwenden können, bleibt die Lösung kosmetisch und löst das zugrunde liegende Problem nicht.
Adam Reis

118

Hier ist meine Version, IMO, es ist leicht zu verstehen und auch elegant.

var str = "foo bar baz"

console.log(

str.split(' ')
   .map(w => w[0].toUpperCase() + w.substr(1).toLowerCase())
   .join(' ')

)
// returns "Foo Bar Baz"


3
Alternativ können Sie die Teilzeichenfolge in der Zuordnung in Kleinbuchstaben schreiben:str.split(' ').map(i => i[0].toUpperCase() + i.substring(1).toLowerCase()).join(' ')
Dave Land

5
Ich bin nicht einverstanden mit dem Anruf .toLowerCase(). Namen wie "McDonald" oder Akronyme wie "ASAP" sollten ihre Großbuchstaben behalten. Wenn jemand tatsächlich eine Zeichenfolge wie "heLLO" übergeben hat, sollte die Anwendung nicht davon ausgehen, dass die Großbuchstaben falsch sind.
Thomas Higginbotham

1
@ ThomasHigginbotham Wie wäre es damit? 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(' '); }
Sean Kendle

Ja, es wäre vorzuziehen, eine Option zum Erzwingen von Kleinbuchstaben bereitzustellen.
Thomas Higginbotham

1
Dies wird unterbrochen, wenn stres sich um ein einzelnes Zeichen handelt.
Madbreaks

103

Hier ist meine Funktion, die in Groß- und Kleinschreibung konvertiert wird, aber auch definierte Akronyme als Groß- und Kleinwörter als Kleinbuchstaben beibehält:

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

Zum Beispiel:

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

1
Ich mochte deine, ich habe auch Probleme beim Umgang mit römischen Zahlen ... habe sie nur mit I, II, III, IV usw. gepatcht
Marcelo

2
Fest. Die Regex in der dritten Zeile wird von geändert worden , /\w\S*/gum /([^\W_]+[^\s-]*) */gper @ awashburn Kommentar oben auf dem abzuhelfen.
Geoffrey Booth

2
Gibt es einen Vorteil, wenn Sie Ihr Regex-Muster verwenden /\b\w+/g, das ich für schneller verständlich halte?
Michael - Wo ist Clay Shirky

2
Nicht, dass ich sehen könnte, ich nahm einfach den Vorschlag eines anderen Kommentators an, um das Problem mit getrennten Wörtern zu lösen. Aber Ihre Regex scheint genauso gut zu funktionieren, und Einfachheit ist immer besser. Für die Nachwelt und zukünftigen Besucher zu diesem Beitrag, ich habe gerade die Regex in der dritten Zeile geändert von /([^\W_]+[^\s-]*) */gbis /\b\w+/gpro @ Michael Kommentar; Bitte kommentieren Sie, wenn Sie einen Fall finden, in dem die kompliziertere Regex erforderlich ist.
Geoffrey Booth

1
Ich habe den regulären Ausdruck der 3. Zeile /\b[\w-\']+/gin geändert, um getrennte Wörter und Apostroph in Wörtern zuzulassen.
Shamasis Bhattacharya

47

Ich bevorzuge das Folgende gegenüber den anderen Antworten. Es stimmt nur mit dem ersten Buchstaben jedes Wortes überein und schreibt es groß. Einfacherer Code, einfacher zu lesen und weniger Bytes. Bestehende Großbuchstaben bleiben erhalten, um verzerrende Akronyme zu vermeiden. Sie können jedoch immer toLowerCase()zuerst Ihre Zeichenfolge aufrufen .

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

Sie können dies zu Ihrem String-Prototyp hinzufügen, wodurch Sie 'my string'.toTitle()Folgendes tun können:

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

Beispiel:


3
Es ist noch schöner als ein Lambdaconst titleCase = (str) => str.replace(/\b\S/g, t => t.toUpperCase());
0xcaff

Ich wollte den IE nicht brechen, aber ja, wenn die Anwendung nicht für ältere Browser geeignet ist, kann sie kürzer sein.
Tom Kay

Dies ist nur eine Teillösung - op fragte, wie eine Zeichenfolge in Groß- und Kleinschreibung konvertiert werden soll. Diese Antwort erreicht das nicht für Eingaben wie NoT qUiITe.
Madbreaks

@Madbreaks Die Frage sah nicht vor, dass Eingaben in gemischten Groß- und Kleinschreibung konvertiert werden sollten. Allerdings habe ich die Erwähnung der Antwort aktualisierttoLowerCase . Seien Sie sich nur bewusst, dass es Akronyme brechen würde. an HTML document: An HTML DocumentvsAn Html Document
Tom Kay

4
@Madbreaks Während Ihr erstes Beispiel erfunden wurde, geben Sie an, dass die Ausgabe unverändert bleiben würde, wenn die Eingabe groß geschrieben würde. Abgesehen davon bin ich der Meinung, dass die Antwort im Ist-Zustand (mit der vorgeschlagenen Bearbeitung toLowerCase) flexibler / nützlicher ist als eine, die die Absichten der Entwickler voraussetzt. Diese Methode spiegelt auch die Funktionalität ähnlicher integrierter Methoden anderer Sprachen wie PHP ( ucwords) und Golang ( strings.Title) wider . .NETZ (TextInfo.ToTitleCaseInteressanterweise funktioniert ) für gemischte Groß- und Kleinschreibung, lässt aber auch vollständig großgeschriebene Zeichenfolgen unverändert.
Tom Kay

20

Ohne Regex nur als Referenz zu verwenden:

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


Vielen Dank für die Regex-freie Lösung!
Lucifer63

20

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

console.log(result) // This Is Very Interesting


Nur eine Frage, das Konstrukt () dient zum Angeben einer Übereinstimmung für eine beliebige Folge von Optionen: Das heißt, (a | b) stimmt mit a oder b überein. Was macht die Konstruktion (.)?
Michael Blackburn

Für alle, die die gleiche Frage hatten, wird ein Ersatz- "Blob" definiert, der im Ersatzabschnitt verwendet wird. Die Blobs sind fortlaufend nummeriert, das erste () wird in $ 1 gesetzt, das zweite in $ 2. Ich fand diese Seite nützlich: javascript.info/tutorial/regular-expressions-methods
Michael Blackburn

Ich bin nicht in der Lage, das oben genannte zum Laufen zu bringen, aber ich bin weit entfernt von einem Regex-Assistenten. Ich verwende 'string'.replace(/^(.)(.*)/,function(s,p1,p2){return p1.toUpperCase()+p2;}) Again, dies funktioniert nur zum Großschreiben des ersten Buchstabens einer Zeichenfolge, aber falls Sie dies benötigen, funktioniert meine Konstruktion.
Michael Blackburn

1
Aus irgendeinem Grund scheint FF35 zu ersticken '$1'.toUpperCase(), anscheinend ist der Großbuchstabe zum Zeitpunkt der Zuweisung des Werts noch nicht fertig. Mit der Funktion 'string'.replace(/^(.){1}/,function(match) { return match.toUpperCase(); })
umgangen

Hallo zusammen, die Antwort ist fest! Ich bin mir ziemlich sicher, dass es funktioniert hat, als ich es zum ersten Mal gepostet habe. Trotzdem danke für die Eingabe!
Simo

17

Sie könnten sofort toLowerCasedie Zeichenfolge und dann nur toUpperCaseden ersten Buchstaben jedes Wortes. Wird ein sehr einfacher 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'));


Ich mag diese Lösung; schön und einfach. Es sieht so aus, als wäre ein bisschen CoffeeScript in Ihre Antwort eingeflossen ( s => s.toUpperCase()). Meine Variante ist, das zu tun, was Sie getan haben, aber das String-Objekt zu erweitern (so kontrovers das auch ist):Object.defineProperty(String.prototype, '_toProperCase', {value:function() {return this.toLowerCase().replace(/\b(\w)/g, function(t) {return t.toUpperCase()})}})
Waz

1
@ Waz, danke für die Ideen! Ich wollte nur klarstellen =>, dass dies eine native Pfeilfunktion (ES6) ist. Der Link springt zu den Mozillla Docs auf ihnen, die auch eine Support-Tabelle bereitstellen.
KevBot

16

Nur für den Fall, dass Sie sich über diese Füllwörter Sorgen machen, können Sie der Funktion immer nur mitteilen, was nicht groß geschrieben werden soll.

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

Hoffe das hilft dir weiter.

bearbeiten

Wenn Sie mit führenden Leimwörtern umgehen möchten, können Sie diese mit einer weiteren Variablen verfolgen:

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

2
Sie können eine Zeichenfolge in ein Array auflösen. So könnten wir portugiesische, spanische, italienische und französische Präpositionen haben:glue ='de|da|del|dos|do|das|des|la|della|delli'.split('|');
Junior Mayhé

Dies gewährleistet nicht die Großschreibung des ersten Wortes. dh and another thingwird and Another Thing. Benötigen Sie nur einen eleganten Weg, um immer das erste Wort groß zu schreiben.
Brad Koch

@BradKoch - Pad mit Leerzeichen, sodass Sie 'und', 'de' usw. als Suchwort verwenden, dann wird 'And Another And Another' durch 'And Another and Another' ersetzt.
Yimin Rong

gut, außer dass es auch Text nach 'und - wie H'Dy oder Nummer Eins
luky

Anstatt einen ternären Operator zu verwenden, können Sie auch einen Fallback verwenden: glue = glue || ['von', 'für', 'und', 'a'];
tm2josep

14

Wenn der in den oben genannten Lösungen verwendete reguläre Ausdruck Sie verwirrt, versuchen Sie diesen Code:

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

Liebe es! Keine Konvertierung in Arrays.
Neelmeg

1
uhhh ... split nicht wandeln es in ein Array, die Sie gerade sehen es nicht so offensichtlich , weil mapMittel für einen Benutzer haben keine []Notation
MalcolmOcean

2
Dies entspricht der Antwort von a8m aus 2 Jahren zuvor.
Michael - Wo ist Clay Shirky

1
Pausen für Single-Char-Eingänge.
Madbreaks

1
@AlexChaffee Überprüfen Sie den Versionsverlauf. a8m hat in der ursprünglichen Antwort keine Pfeilfunktion verwendet.
Vielen Dank, dass Sie

9

Ich habe diese Funktion erstellt, die Nachnamen (also keine Groß- und Kleinschreibung) wie "McDonald" oder "MacDonald" oder "O'Toole" oder "D'Orazio" verarbeiten kann. Deutsche oder niederländische Namen mit "van" oder "von", die oft in Kleinbuchstaben geschrieben sind, werden jedoch nicht behandelt. Ich glaube, "de" ist oft auch in Kleinbuchstaben wie "Robert de Niro". Diese müssten noch angegangen werden.

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

1
+1 für Namensbewusstsein. Behandelt "macy" aber auch nicht richtig.
Brian

Dies war die einzige Funktion, die die Umwandlung von Groß- und Kleinschreibung in die richtige Groß- und Kleinschreibung korrekt handhabte und Initialen wie "US Virgin Islands" bemerkte.
Rodrigo Polo

Sie können das macyProblem \b((m)(a?c))?(\w)\b((m)(a?c))?(\w)(?!\s)
Ste

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

Scheint zu funktionieren ... Getestet mit dem oben Gesagten: "Der schnell braune Fuchs? / Springt / ^ über ^ den ¡faulen! Hund ..." und "C: / Programme / einige Anbieter / ihre 2. Anwendung / a file1.txt ".

Wenn Sie 2Nd anstelle von 2nd möchten, können Sie zu wechseln /([a-z])(\w*)/g .

Die erste Form kann vereinfacht werden als:

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

7

Versuche dies

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

Beispiel

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

7

Wenn Sie in Ihrem Code Bibliotheken von Drittanbietern verwenden können, hat lodash eine Hilfsfunktion für uns.

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'


7

Versuchen Sie dies auf kürzestem Weg:

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

7

ES 6

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

sonst

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

Nur ein Kopf hoch, sollte wahrscheinlich sein, s.slice(0, 1).toUpperCase()wenn Sie noch diesen ersten Buchstaben wollen.
WindsofTime

@jssridhar Sie sollten auch den Code in ES6 korrigieren.
Caiosm1005

1
str
Bricht,

@ jssridhar könnte besser für uns sein .charAt(0).toUpperCase().
Roydukkey

2
Duplikat der Antwort von a8m
Danke,

6

Die meisten dieser Antworten scheinen die Möglichkeit der Verwendung des Wortgrenzen-Metazeichens (\ b) zu ignorieren. Eine kürzere Version von Greg Deans Antwort, die sie verwendet:

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

Funktioniert auch für getrennte Namen wie Jim-Bob.


2
Ist eine elegante Teillösung, funktioniert aber nicht mit Akzent- oder Großbuchstaben. Ich bekomme "Sofía Vergara" => "SofíA Vergara" oder "Sofía VERGARA" => "SofíA VERGARA". Der zweite Fall könnte mit der Funktion apply .toLowerCase () vor .replace (...) gelöst werden. Der erste Fall muss einen richtigen regulären Ausdruck finden.
Asereware

2
Hmm, das scheint ein Fehler in der Regex-Implementierung zu sein. Ich würde denken, dass Zeichen mit Akzent Wortzeichen sein sollten (Sie haben jedoch Recht, da dies in diesen Fällen nicht funktioniert).
lewax00

\wEnthält nur die Zeichen [A-Za-z0-9_], nicht alle Buchstaben. Dafür müssten Sie die Unicode-Kategorie verwenden \p{L}. Sie benötigen den /uModifikator (siehe hier ) und eine andere Lösung für \b, die nur zwischen \Wund \w(siehe hier )
funktioniert

6

Ich denke, das einfachste ist die Verwendung von CSS.

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

Ich habe den Code aktualisiert und getestet. Es sollte jetzt funktionieren.
Wondim

Sie können CSS nur in einem Bruchteil der Umgebungen verwenden, in denen JS verwendet wird. Daher ist diese Lösung nicht realisierbar. Auch Inline-Stile sollten unbedingt vermieden werden.
Madbreaks

5

Verwenden Sie /\S+/gzur Unterstützung diakritische Zeichen:

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

Allerdings: " s unshine ( y ellow)" ⇒ " S unshine ( y ellow)"


5

Ich wollte meine eigene Antwort hinzufügen, da ich eine robuste toTitleCaseFunktion benötigte , die die hier aufgeführten Grammatikregeln berücksichtigt (von Google empfohlener Artikel). Es gibt verschiedene Regeln, die von der Länge der Eingabezeichenfolge abhängen. Unten finden Sie die Funktion + Unit-Tests.

Die Funktion konsolidiert auch Leerzeichen und entfernt Sonderzeichen (ändern Sie den regulären Ausdruck an Ihre Bedürfnisse).

toTitleCase-Funktion

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 zur Sicherstellung der Richtigkeit

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

Bitte beachten Sie, dass ich einige Sonderzeichen aus den bereitgestellten Zeichenfolgen entferne. Sie müssen den regulären Ausdruck anpassen, um die Anforderungen Ihres Projekts zu erfüllen.


Ich bevorzuge diese Lösung, da sie sich wirklich um den Titelfall kümmert. Es ist nicht "Vom Winde verweht", sondern "Vom Winde verweht"
russellmania

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

1
Funktioniert für das Sample und macht o'henryaber komische Sachen mit horse's mouth.
Michael - Wo ist Clay Shirky

"john f. kennEdy".toLowerCase().replace(/\b\S/g, t => t.toUpperCase())besser 🤔
w3debugger

Ich wollte die Antwort von @ Proximo nicht bearbeiten: Die \bund \Ssind Sonderzeichenklassen , die "Wortgrenze" und "einzelnes Nicht-Leerzeichen" bezeichnen. Der reguläre Ausdruck stimmt also mit jedem einzelnen Zeichen überein, das einer Wortgrenze folgt, und aktiviert dieses Zeichen durch Anwenden der angegebenen Pfeilfunktion.
Jens

4

Mit der "lewax00" -Lösung habe ich diese einfache Lösung erstellt, die "w" beginnend mit Leerzeichen oder "w" erzwingt, die de word initiieren, aber die zusätzlichen Zwischenräume nicht entfernen kann.

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

Das Ergebnis ist "Sofía Vergara".


4

Hier ist meine Funktion, die sich um akzentuierte Zeichen kümmert (wichtig für Französisch!) Und die Behandlung von niedrigeren Ausnahmen ein- und ausschalten kann. Ich hoffe, das hilft.

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

4

Wir haben hier im Büro eine Diskussion geführt und sind der Meinung, dass der Versuch, die Art und Weise, wie Personen Namen eingeben, automatisch so zu korrigieren, wie Sie es möchten, mit möglichen Problemen behaftet ist.

Wir haben uns mehrere Fälle ausgedacht, in denen verschiedene Arten der automatischen Großschreibung auseinanderfallen und diese nur für englische Namen gelten. Jede Sprache hat ihre eigene Komplexität.

Probleme beim Großschreiben des ersten Buchstabens jedes Namens:

• Akronyme wie IBM dürfen nicht eingegeben werden und werden zu Ibm.

• Der Name McDonald würde sich in Mcdonald verwandeln, was falsch ist, das gleiche gilt auch für MacDonald.

• Doppelte Namen wie Marie-Tonks würden zu Marie-Tonks.

• Namen wie O'Connor würden zu O'connor.

Für die meisten von ihnen könnten Sie benutzerdefinierte Regeln schreiben, um damit umzugehen. Dies hat jedoch weiterhin Probleme mit Akronymen wie zuvor und Sie erhalten ein neues Problem:

• Wenn Sie eine Regel hinzufügen, um Namen mit Mac wie MacDonald zu korrigieren, werden die Unterbrechungsnamen wie Macy zu MacY.

Die einzige Lösung, die wir gefunden haben und die niemals falsch ist, besteht darin, jeden Buchstaben groß zu schreiben, was eine Brute-Force-Methode ist, die das DBS anscheinend auch verwendet.

Wenn Sie also den Prozess automatisieren möchten, ist es so gut wie unmöglich, auf ein Wörterbuch mit jedem einzelnen Namen und Wort zu verzichten und darauf, wie es kapituliert werden sollte. Wenn Sie keine Regel haben, die alles abdeckt, verwenden Sie es nicht so, wie es ist ärgert nur Ihre Benutzer und fordert Personen, die ihre Namen korrekt eingeben möchten, auf, woanders hinzugehen.


4

Hier ist eine andere Lösung mit CSS (und Javascript, wenn der zu transformierende Text in Großbuchstaben geschrieben ist):

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

Für diejenigen von uns, die Angst vor regulären Ausdrücken haben (lol):

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

Meine einzeilige Lösung:

String.prototype.capitalizeWords = function() {
    return this.split(" ").map(function(ele){ return ele[0].toUpperCase() + ele.slice(1).toLowerCase();}).join(" ");
};

Anschließend können Sie die Methode capitalizeWords()für eine beliebige Zeichenfolge aufrufen . Zum Beispiel:

var myS = "this actually works!";
myS.capitalizeWords();

>>> This Actually Works

Meine andere Lösung:

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

Anschließend können Sie die Methode capitalizeWords()für eine beliebige Zeichenfolge aufrufen . Zum Beispiel:

var myStr = "this one works too!";
myStr.capitalizeWords();

>>> This One Works Too

Alternative Lösung basierend auf Greg Dean Antwort:

function capitalizeFirstLetter(word) {
    return word[0].toUpperCase() + word.slice(1).toLowerCase();
}
String.prototype.capitalizeWords = function() {
    return this.replace(/\w\S*/g, capitalizeFirstLetter);
};

Anschließend können Sie die Methode capitalizeWords()für eine beliebige Zeichenfolge aufrufen . Zum Beispiel:

var myString = "yes and no";
myString.capitalizeWords()

>>> Yes And No

3

Überrascht zu sehen, dass niemand die Verwendung von Ruheparametern erwähnte. Hier ist ein einfacher Einzeiler, der ES6 Rest-Parameter verwendet.

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


2

Dies basiert auf meiner Lösung für FreeCodeCamps Bonfire "Title Case" , bei der Sie zuerst die angegebene Zeichenfolge in Kleinbuchstaben konvertieren und dann jedes Zeichen, das ein Leerzeichen in Großbuchstaben umwandelt, konvertieren müssen.

Ohne Regex zu verwenden:

function titleCase(str) {
 return str.toLowerCase().split(' ').map(function(val) { return val.replace(val[0], val[0].toUpperCase()); }).join(' ');
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.