Wie kann man mit C # das erste Zeichen jedes Wortes oder das erste Zeichen einer ganzen Zeichenfolge groß schreiben?

76

Ich könnte meinen eigenen Algorithmus schreiben, aber ich denke, es sollte das Äquivalent zu Rubys Humanisierung in C # geben.

Ich habe es gegoogelt, aber nur Wege gefunden, Datteln zu humanisieren.

Beispiele:

  • Eine Möglichkeit, "Lorem Lipsum Et" in "Lorem Lipsum Et" zu verwandeln
  • Eine Möglichkeit, "Lorem Lipsum et" in "Lorem Lipsum Et" zu verwandeln
marcgg
quelle
1
Ich sage aus irgendeinem Grund gerne Lorem Lipsum ^^
marcgg
3
Es gibt immer Regex! string strToCap = strSource.ToLower (); Regex rCapitalize = neuer Regex ("(? <= [! \.?] \ S +) [A-Za-z]"); strToCap = rCapitalize.Replace (strToCap, m => {return m.Value.ToUpper ();}); ... aber dann hättest du ZWEI Probleme. :)
Rijipooh
3
Da die akzeptierte Antwort auf Code verweist, der das Gegenteil der ursprünglichen Frage bewirkt, habe ich die Frage so bearbeitet, dass sie nach beiden Richtungen fragt, in der Hoffnung, dass diese Frage für zukünftige Benutzer, die darüber stolpern, nicht völlig verwirrend ist .
Daniel Earwicker
Obwohl dies möglicherweise nicht durch die Beispielzeichenfolge des OP angesprochen wird, verlieren viele Menschen die Unterscheidung zwischen Titelfall und Großschreibung. In der Groß- und Kleinschreibung von Titeln werden keine gebräuchlichen Wörter großgeschrieben. Obwohl dies oben funktioniert, ist es die falsche Lösung. Der Hund ist schnell vs Der Hund ist schnell. Letzteres ist Kapitalisierung.
Demongolem

Antworten:

133

Wie in den Kommentaren der Antwort von @ miguel erläutert , können Sie TextInfo.ToTitleCasedie seit .NET 1.1 verfügbare verwenden. Hier ist ein Code, der Ihrem Beispiel entspricht:

string lipsum1 = "Lorem lipsum et";

// Creates a TextInfo based on the "en-US" culture.
TextInfo textInfo = new CultureInfo("en-US",false).TextInfo;

// Changes a string to titlecase.
Console.WriteLine("\"{0}\" to titlecase: {1}", 
                  lipsum1, 
                  textInfo.ToTitleCase( lipsum1 )); 

// Will output: "Lorem lipsum et" to titlecase: Lorem Lipsum Et

Es werden Großbuchstaben wie "LOREM LIPSUM ET" ignoriert, da Fälle behandelt werden, in denen Akronyme im Text enthalten sind (sodass " NAMBLA " nicht zu "nambla" oder "Nambla" wird).

Wenn Sie jedoch nur das erste Zeichen nutzen möchten , können Sie die Lösung tun , die über ist hier ... oder Sie könnten nur die Zeichenfolge aufgeteilt und die erste in der Liste nutzen:

string lipsum2 = "Lorem Lipsum Et";

string lipsum2lower = textInfo.ToLower(lipsum2);

string[] lipsum2split = lipsum2lower.Split(' ');

bool first = true;

foreach (string s in lipsum2split)
{
    if (first)
    {
        Console.Write("{0} ", textInfo.ToTitleCase(s));
        first = false;
    }
    else
    {
        Console.Write("{0} ", s);
    }
}

// Will output: Lorem lipsum et 
Spoike
quelle
Woher wissen mehr Menschen nichts davon? Dies ist eine brillante eingebaute Methode, danke
Coops
6
Haha 3 Jahre später und NAMBLA bringt mich immer noch zum Lachen, oh und +1 für ToTitleCase ()
Jason Kulatunga
2
Gefundenes Problem mit ToTitleCase 1st wird 1St.
Joghurt der Weise
1
Zweites Problem mit ToTitleCase gefunden - & nbsp; wird & Nbsp;
Brain2000
2
@ Brain2000 Wenn Sie wissen, dass die Zeichenfolge HTML-Entitäten enthält, sollten Sie Ihren Code dies vor der Verwendung behandeln lassen ToTitleCase.
Spoike
33

Verwenden Sie reguläre Ausdrücke, damit dies viel sauberer aussieht:

string s = "the quick brown fox jumps over the lazy dog";
s = Regex.Replace(s, @"(^\w)|(\s\w)", m => m.Value.ToUpper());
Xela
quelle
1
Erweitern der Antwort: string s = "Das schnelle bRown fOx juMps über das LAzy doG"; s = Regex.Replace (s.ToLower (), @ "(^ \ w) | (\ s \ w)", m => m.Value.ToUpper ());
Mcandal
8
Dieser Einzeiler ohne Regex funktioniert auch: s = CultureInfo.CurrentCulture.TextInfo.ToTitleCase (value.ToLower ());
Roberto
2
@Roberto - "hEm" -> regex = "HEm"; "hEm" -> TitleCase = "Hem"
zzxyz
Ich denke, das ist einfacherRegex.Replace(s, @"\b([a-z])", m => m.Value.ToUpper())
John Henckel
27

Es gibt noch eine andere elegante Lösung:

Definieren Sie die Funktion ToTitleCasein einer statischen Klasse Ihres Projekts

using System.Globalization;

public static string ToTitleCase(this string title)
{
    return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(title.ToLower()); 
}

Und verwenden Sie es dann wie eine Zeichenfolgenerweiterung an einer beliebigen Stelle in Ihrem Projekt:

"have a good day !".ToTitleCase() // "Have A Good Day !"
G. Busato
quelle
1
Sie sollten auch verwenden, title.ToLower()bevor Sie an übergeben ToTitleCase. Andernfalls werden Großbuchstaben nicht ersetzt.
RA.
Elegante Lösung, funktioniert gut für mich, danke!
LuckyLuke82
2

Wenn Sie nur das erste Zeichen groß schreiben möchten, fügen Sie dies einfach in eine eigene Dienstprogrammmethode ein:

return string.IsNullOrEmpty(str) 
    ? str
    : str[0].ToUpperInvariant() + str.Substring(1).ToLowerInvariant();

Es gibt auch eine Bibliotheksmethode, um das erste Zeichen jedes Wortes groß zu schreiben:

http://msdn.microsoft.com/en-us/library/system.globalization.textinfo.totitlecase.aspx

Daniel Earwicker
quelle
Das gibt Ihnen nur den Titel: "Lorem Ipsum Et", nicht den Satz: "Lorem ipsum et", richtig?
Vinny
Ich denke, das macht das Gegenteil.
Çağdaş Tekin
Ich habe das gedacht, aber ToTitleCase ist das Gegenteil von dem, was das OP will.
Pat Hermens
Mein schlechtes Ich dachte, es würde funktionieren, aber es tat nicht. Titlecase scheint den Trick zu tun
Marcgg
Uhhh ... Was ist Titlecase? Meinen Sie ToTitleCase? Es macht das Gegenteil von dem, was Sie ursprünglich gefragt haben. Es ist auch das allererste, was ich in meiner ursprünglichen Antwort gepostet habe. Ich gebe auf.
Daniel Earwicker
1

Die CSS-Technik ist in Ordnung, ändert jedoch nur die Darstellung der Zeichenfolge im Browser. Eine bessere Methode besteht darin, den Text selbst groß zu schreiben, bevor er an den Browser gesendet wird.

Die meisten der oben genannten Implikationen sind in Ordnung, aber keine von ihnen befasst sich mit der Frage, was passiert, wenn Sie gemischte Groß- und Kleinschreibung haben, die beibehalten werden müssen, oder wenn Sie beispielsweise echte Groß- und Kleinschreibung verwenden möchten:

"Wo man in den USA promoviert"

oder

"IRS Form UB40a"

Auch bei Verwendung von CultureInfo.CurrentCulture.TextInfo.ToTitleCase (Zeichenfolge) werden Großbuchstaben wie in "Sport und MLB-Baseball" beibehalten, was zu "Sport und MLB-Baseball" wird. Wenn jedoch die gesamte Zeichenfolge in Großbuchstaben geschrieben wird, verursacht dies ein Problem.

Deshalb habe ich eine einfache Funktion zusammengestellt, mit der Sie Groß- und Kleinbuchstaben beibehalten und kleine Wörter in Kleinbuchstaben schreiben können (wenn sie nicht am Anfang und Ende der Phrase stehen), indem Sie sie in String-Arrays für SpecialCases und LowerCases einfügen:

public static string TitleCase(string value) {
        string titleString = ""; // destination string, this will be returned by function
        if (!String.IsNullOrEmpty(value)) {
            string[] lowerCases = new string[12] { "of", "the", "in", "a", "an", "to", "and", "at", "from", "by", "on", "or"}; // list of lower case words that should only be capitalised at start and end of title
            string[] specialCases = new string[7] { "UK", "USA", "IRS", "UCLA", "PHd", "UB40a", "MSc" }; // list of words that need capitalisation preserved at any point in title
            string[] words = value.ToLower().Split(' ');
            bool wordAdded = false; // flag to confirm whether this word appears in special case list
            int counter = 1;
            foreach (string s in words) {

                // check if word appears in lower case list
                foreach (string lcWord in lowerCases) {
                    if (s.ToLower() == lcWord) {
                        // if lower case word is the first or last word of the title then it still needs capital so skip this bit.
                        if (counter == 0 || counter == words.Length) { break; };
                        titleString += lcWord;
                        wordAdded = true;
                        break;
                    }
                }

                // check if word appears in special case list
                foreach (string scWord in specialCases) {
                    if (s.ToUpper() == scWord.ToUpper()) {
                        titleString += scWord;
                        wordAdded = true;
                        break;
                    }
                }

                if (!wordAdded) { // word does not appear in special cases or lower cases, so capitalise first letter and add to destination string
                    titleString += char.ToUpper(s[0]) + s.Substring(1).ToLower();
                }
                wordAdded = false;

                if (counter < words.Length) {
                    titleString += " "; //dont forget to add spaces back in again!
                }
                counter++;
            }
        }
        return titleString;
    }

Dies ist nur eine schnelle und einfache Methode - und kann wahrscheinlich ein wenig verbessert werden, wenn Sie mehr Zeit damit verbringen möchten.

Wenn Sie die Großschreibung kleinerer Wörter wie "a" und "of" beibehalten möchten, entfernen Sie sie einfach aus dem String-Array für Sonderfälle. Unterschiedliche Organisationen haben unterschiedliche Regeln für die Kapitalisierung.

Sie können ein Beispiel für diesen Code in Aktion auf dieser Site sehen: Egg Donation London - Diese Site erstellt automatisch Breadcrumb-Trails oben auf den Seiten, indem sie die URL z. B. "/ services / uk-egg-bank / Introduction" analysiert Der Ordnername im Trail enthält Bindestriche, die durch Leerzeichen ersetzt werden, und der Ordnername wird groß geschrieben, sodass aus der UK-Eierbank die UK-Eierbank wird. (Beibehaltung des Großbuchstabens 'UK')

Eine Erweiterung dieses Codes könnte darin bestehen, eine Nachschlagetabelle mit Akronymen und Groß- / Kleinbuchstaben in einer gemeinsam genutzten Textdatei, Datenbanktabelle oder einem Webdienst zu haben, damit die Liste der Wörter mit gemischten Groß- und Kleinschreibung von einem einzigen Ort aus verwaltet und auf viele verschiedene angewendet werden kann Anwendungen, die auf der Funktion beruhen.

Myke Black
quelle
1

Alle Beispiele scheinen die anderen Zeichen zuerst zu senken, was ich nicht brauchte.

customerName= CustomerName<- Welches ist was ich wollte

this is an example = This Is An Example

public static string ToUpperEveryWord(this string s)
{
    // Check for empty string.  
    if (string.IsNullOrEmpty(s))
    {
        return string.Empty;
    }

    var words = s.Split(' ');

    var t = "";
    foreach (var word in words)
    {
        t += char.ToUpper(word[0]) + word.Substring(1) + ' ';
    }
    return t.Trim();
}
Demodave
quelle
0

In .NET gibt es keine vorgefertigte Lösung für die ordnungsgemäße sprachliche Erfassung. Welche Art von Kapitalisierung streben Sie an? Befolgen Sie die Konventionen des Chicago Manual of Style? AMA oder MLA? Sogar die Großschreibung von einfachen englischen Sätzen hat Tausende von besonderen Ausnahmen für Wörter. Ich kann nicht mit dem sprechen, was Ruby humanisiert, aber ich stelle mir vor, dass es wahrscheinlich nicht den sprachlichen Regeln der Großschreibung folgt und stattdessen etwas viel Einfacheres tut.

Intern sind wir auf dasselbe Problem gestoßen und mussten einen ziemlich großen Code schreiben, um die korrekte (in unserer kleinen Welt) Schreibweise von Artikeltiteln zu handhaben, ohne die Satzkapitalisierung zu berücksichtigen. Und es wird tatsächlich "unscharf" :)

Es hängt wirklich davon ab, was Sie brauchen - warum versuchen Sie, die Sätze in die richtige Großschreibung umzuwandeln (und in welchem ​​Kontext)?

patjbs
quelle
0

Ich habe das gleiche mit benutzerdefinierten Erweiterungsmethoden erreicht. Verwenden Sie für den ersten Buchstaben des ersten Teilstrings die Methode yourString.ToFirstLetterUpper(). Verwenden Sie für den ersten Buchstaben jeder Unterzeichenfolge mit Ausnahme von Artikeln und einigen Aussagen die Methode yourString.ToAllFirstLetterInUpper(). Unten ist ein Konsolenprogramm:

class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("this is my string".ToAllFirstLetterInUpper());
            Console.WriteLine("uniVersity of lonDon".ToAllFirstLetterInUpper());
        }
    }

    public static class StringExtension
    {
        public static string ToAllFirstLetterInUpper(this string str)
        {
            var array = str.Split(" ");

            for (int i = 0; i < array.Length; i++)
            {
                if (array[i] == "" || array[i] == " " || listOfArticles_Prepositions().Contains(array[i])) continue;
                array[i] = array[i].ToFirstLetterUpper();
            }
            return string.Join(" ", array);
        }

        private static string ToFirstLetterUpper(this string str)
        {
            return str?.First().ToString().ToUpper() + str?.Substring(1).ToLower();
        }

        private static string[] listOfArticles_Prepositions()
        {
            return new[]
            {
                "in","on","to","of","and","or","for","a","an","is"
            };
        }
    }

AUSGABE

This is My String
University of London
Process finished with exit code 0.
Imran Faruqi
quelle