Machen Sie den ersten Buchstaben eines Strings in Großbuchstaben (mit maximaler Leistung)

447

Ich habe eine DetailsViewmit einem , TextBox und ich möchte , dass die Eingangsdaten werden immer gespeichert mit dem ersten Buchstaben CAPITAL.

Beispiel:

"red" --> "Red"
"red house" --> " Red house"

Wie kann ich diese maximale Leistung erreichen ?


HINWEIS :
Basierend auf den Antworten und den Kommentaren unter den Antworten denken viele Leute, dass hier nach der Großschreibung aller Wörter in der Zeichenfolge gefragt wird . ZB => Red House ist es nicht, aber wenn Sie danach suchen , suchen Sie nach einer der Antworten, die TextInfodie ToTitleCaseMethode von verwenden. (HINWEIS: Diese Antworten sind für die tatsächlich gestellte Frage falsch .) Informationen finden
Sie im TextInfo.ToTitleCase-Dokument (berührt keine Wörter mit Großbuchstaben - sie werden als Akronyme betrachtet; möglicherweise werden Kleinbuchstaben in der Mitte von Wörtern verwendet, die "nicht" sein sollten gesenkt, zB "McDonald" => "Mcdonald"; es wird nicht garantiert, dass alle kulturspezifischen Feinheiten bezüglich der Kapitalisierungsregeln behandelt werden.)


HINWEIS :
Die Frage ist nicht eindeutig , ob Buchstaben nach dem ersten werden sollten gezwungen zu Fall zu senken . Bei der akzeptierten Antwort wird davon ausgegangen, dass nur der erste Buchstabe geändert werden sollte . Wenn Sie alle Buchstaben in der Zeichenfolge außer dem ersten in Kleinbuchstaben erzwingen möchten , suchen Sie nach einer Antwort mitToLower , die ToTitleCase und nicht enthält .

Dylan-Myers
quelle
7
@ Bobby: Es ist kein Duplikat: Das OP fragt, ob der erste Buchstabe eines Strings groß geschrieben werden soll. Die Frage im Link schreibt den ersten Buchstaben jedes Wortes groß.
GvS
1
@GvS: Die erste Antwort ist sehr detailliert und der erste Codeblock ist genau das , wonach er sucht. Außerdem besteht zwischen der Großschreibung jedes Wortes und nur des ersten Wortes nur ein Schleifendifferenz.
Bobby
Haben Sie das jemals erfolgreich gelöst? Benötigen Sie noch Hilfe dabei?
Jcolebrand
1
Aber Sie sagten, und ich zitiere: "Machen Sie den ersten Buchstaben von JEDEM WORT in Großbuchstaben". Warum also "Rotes Haus" -> "Rotes Haus"? Warum ist das "h" von "Haus" kein Großbuchstabe?
Guillermo Gutiérrez
Eine Antwort wurde hinzugefügt, da die meisten Antworten fehlschlagen, wenn Sie am Anfang ein Leerzeichen haben. Um dies nicht bei jeder Antwort zu posten, werde ich es hier einmal posten.
Noctis

Antworten:

583

Auf C # 8 aktualisiert

public static class StringExtensions
{
    public static string FirstCharToUpper(this string input) =>
        input switch
        {
            null => throw new ArgumentNullException(nameof(input)),
            "" => throw new ArgumentException($"{nameof(input)} cannot be empty", nameof(input)),
            _ => input.First().ToString().ToUpper() + input.Substring(1)
        };
}

C # 7

public static class StringExtensions
{
    public static string FirstCharToUpper(this string input)
    {
        switch (input)
        {
            case null: throw new ArgumentNullException(nameof(input));
            case "": throw new ArgumentException($"{nameof(input)} cannot be empty", nameof(input));
            default: return input.First().ToString().ToUpper() + input.Substring(1);
        }
    }
}

Wirklich alte Antworten

public static string FirstCharToUpper(string input)
{
    if (String.IsNullOrEmpty(input))
        throw new ArgumentException("ARGH!");
    return input.First().ToString().ToUpper() + String.Join("", input.Skip(1));
}

EDIT : Diese Version ist kürzer. Für eine schnellere Lösung werfen Sie einen Blick auf die Antwort von Equiso

public static string FirstCharToUpper(string input)
{
    if (String.IsNullOrEmpty(input))
        throw new ArgumentException("ARGH!");
    return input.First().ToString().ToUpper() + input.Substring(1);
}

EDIT 2 : Die wahrscheinlich schnellste Lösung ist die von Darren (es gibt sogar einen Benchmark), obwohl ich die string.IsNullOrEmpty(s)Validierung ändern würde, um eine Ausnahme auszulösen, da die ursprüngliche Anforderung erwartet, dass ein erster Buchstabe vorhanden ist, damit er in Großbuchstaben geschrieben werden kann. Beachten Sie, dass dieser Code für eine generische Zeichenfolge funktioniert und nicht speziell für gültige Werte aus dem Textbox.

Carlos Muñoz
quelle
2
Weil der erste Parameter von String.Joinein Trennzeichen ist, mit dem Zeichenfolgen verbunden werden sollen, die mit dem zweiten Parameter angegeben wurden.
Dialecticus
27
Ihre Antwort gefällt mir sehr gut, var arr = input.ToCharArray(); arr[0] = Char.ToUpperInvariant(arr[0]); return new String(arr);würde aber wahrscheinlich an Geschwindigkeit gewinnen, da Sie weniger unveränderliche Objekte erstellen (und insbesondere die überspringen String.Join). Dies hängt natürlich von der Länge der Zeichenfolge ab.
Flindeberg
3
Genial - Die Verwendung von Linq macht sehr deutlich, was dieser Code bewirkt.
Daniel James Bryars
7
Hmmm ... Technisch soll diese Rückkehr "Argh!"mit der halten Versalien ersten Briefes Regel. ;)
jp2code
2
@ jp2code Da das Großschreiben eines nicht vorhandenen ersten Buchstabens in einer Null- oder leeren Zeichenfolge so ist, als würde man von einem schwangeren Delphing geschlagen, dann ist ALL CAPS ARGH! ist die richtige Schreibweise. urbandictionary.com/define.php?term=ARGH&defid=67839
Carlos Muñoz
319
public string FirstLetterToUpper(string str)
{
    if (str == null)
        return null;

    if (str.Length > 1)
        return char.ToUpper(str[0]) + str.Substring(1);

    return str.ToUpper();
}

Alte Antwort: Dies macht jeden ersten Buchstaben in Großbuchstaben

public string ToTitleCase(string str)
{
    return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(str.ToLower());
}
Diego Torres
quelle
Dadurch wird jedoch jeder erste Buchstabe eines Wortes in Großbuchstaben umgewandelt, nicht nur das erste Zeichen einer Zeichenfolge.
GvS
@GvS, darum bittet dich die Frage.
thattolleyguy
17
Er fragt "Rotes Haus" => "Rotes Haus". ToTitleCase gibt Ihnen "Red House".
GvS
1
hilfreich für mich. Großartig
Ehsan Sajjad
1
Ich bin mir nicht sicher, aber char + string verursacht ein Boxen. Nur für den Fall, dass maximale Leistung die Voraussetzung ist.
Nawfal
163

Der richtige Weg ist, Kultur zu nutzen:

System.Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(word.ToLower())

Hinweis: Dadurch wird jedes Wort in einer Zeichenfolge groß geschrieben, z. B. "Rotes Haus" -> "Rotes Haus". Die Lösung wird auch Großbuchstaben in Worten verwenden, z. B. "alter McDonald" -> "alter Mcdonald".

Pierre-Yves Guillemet
quelle
4
Dies ist der beste Weg, dies zu tun, anstatt das Rad neu zu erfinden und zu versuchen, eine eigene Version davon zu schreiben.
Alexey Shevelyov
12
Das Problem, das ich dabei habe, ist, dass potenziell gültige Großbuchstaben in der Mitte der Zeichenfolge gelöscht werden. zB McNames
Jecoms
29
Dies ist eine falsche Antwort, da aus "Rotes Haus" "Rotes Haus" wird (beachten Sie das "H")!
Spaark
21
Sechs Jahre nachdem die Frage gestellt wurde, lesen Sie bitte die vorhandenen Antworten und ihre Kommentare gründlicher durch . Wenn Sie davon überzeugt sind, dass Sie eine bessere Lösung haben, zeigen Sie die Situationen, in denen sich Ihre Antwort so verhält, wie Sie es für überlegen halten, und insbesondere, wie sich diese von den vorhandenen Antworten unterscheidet. 1) Equiso hat diese Option bereits in der zweiten Hälfte seiner Antwort behandelt. 2) In vielen Situationen ToLowerist dies ein Fehler, da dadurch die Großschreibung mitten im Wort gelöscht wird, z. B. "McDonalds". 3) Bei der Frage geht es darum , nur das erste Wort der Zeichenfolge zu ändern , nicht um TitleCase.
ToolmakerSteve
10
Dies verwandelt die Eingabe in "Title Case" - also verwandelt es "Red Horse" in "Red Horse" - während die Person, die ausdrücklich fragt, erklärt, dass sie dies NICHT tun soll (und "Red Horse" zurückgibt). Dies ist nicht der richtige Weg.
Hekkaryk
68

Ich habe die schnellste Methode von http://www.dotnetperls.com/uppercase-first-letter übernommen und in die Erweiterungsmethode konvertiert:

    /// <summary>
    /// Returns the input string with the first character converted to uppercase, or mutates any nulls passed into string.Empty
    /// </summary>
    public static string FirstLetterToUpperCaseOrConvertNullToEmptyString(this string s)
    {
        if (string.IsNullOrEmpty(s))
            return string.Empty;

        char[] a = s.ToCharArray();
        a[0] = char.ToUpper(a[0]);
        return new string(a);
    }

ANMERKUNG: Der Grund für die Verwendung ToCharArrayist schneller als die Alternative char.ToUpper(s[0]) + s.Substring(1), da nur eine Zeichenfolge zugewiesen wird, während der SubstringAnsatz eine Zeichenfolge für die Teilzeichenfolge und dann eine zweite Zeichenfolge zum Erstellen des Endergebnisses zuweist.


EDIT : So sieht dieser Ansatz aus, kombiniert mit dem ersten Test von Carlos Muñoz akzeptierte Antwort :

    /// <summary>
    /// Returns the input string with the first character converted to uppercase
    /// </summary>
    public static string FirstLetterToUpperCase(this string s)
    {
        if (string.IsNullOrEmpty(s))
            throw new ArgumentException("There is no first letter");

        char[] a = s.ToCharArray();
        a[0] = char.ToUpper(a[0]);
        return new string(a);
    }
Darren
quelle
Wow, danke, dass Sie Leistungsmetriken gefunden haben, um eine Lösung mit überlegener Leistung zu zeigen!
ToolmakerSteve
@ToolmakerSteve, ich mag diese Lösung, da sie zwar schneller zu sein scheint als andere, aber es gibt ein kleines Problem damit. Wenn Sie null übergeben, sollten Sie keine leere Zeichenfolge als Ausgabe erhalten. Tatsächlich würde ich argumentieren, dass selbst das Übergeben einer leeren Zeichenfolge eine Ausnahme auslösen sollte, da das OP nach dem ersten Buchstaben fragt . Sie können auch die Antwort anderer Personen kommentieren, bevor Sie sie bearbeiten.
Carlos Muñoz
@ CarlosMuñoz - Es wurde in Meta diskutiert, ob die Antworten anderer Leute "verbessert" werden sollen. Der Konsens war: "Wenn Sie eine Antwort verbessern können, dann tun Sie dies - niemand" besitzt "eine Antwort, nicht einmal der ursprüngliche Autor - das Ziel ist es, die bestmöglichen Antworten zu haben". Sie können die Bearbeitung natürlich bearbeiten oder rückgängig machen. In diesem Fall würde die allgemeine Höflichkeit die Version des Originalautors zum Endergebnis machen, und ich würde mich mit Kommentaren zufrieden geben. Normalerweise schreibe ich auch einen Kommentar in die Änderung, die ich vornehme; Ich entschuldige mich, wenn ich es nicht getan habe.
ToolmakerSteve
@ CarlosMuñoz - insbesondere gibt es viele, viele Antworten in SO, die nicht aktiv gepflegt werden. Wenn eine Änderung eine Antwort verbessern würde, warum sollte sie dann in einem Kommentar vergraben bleiben? Wenn der Autor seine Antworten aktiv überwacht, wird er die Änderung nach eigenem Ermessen vornehmen. Wenn dies nicht der Fall ist, wurde die Antwort zum Nutzen aller verbessert. Dieses Prinzip gilt insbesondere für alte Fragen und Antworten wie dieses.
ToolmakerSteve
Übrigens stimme ich @ CarlosMuñoz bezüglich des Tests zu Beginn der Methode zu - seine Version dieses Tests ist ein besserer Programmierstil -, der return string.Emptyhier einen "schlechten" Aufruf der Methode verbergen würde.
ToolmakerSteve
46

Sie können die "ToTitleCase-Methode" verwenden.

string s = new CultureInfo("en-US").TextInfo.ToTitleCase("red house");
//result : Red House

Diese Erweiterungsmethode löst jedes Titelfallproblem.

einfach zu bedienen

string str = "red house";
str.ToTitleCase();
//result : Red house

string str = "red house";
str.ToTitleCase(TitleCase.All);
//result : Red House

die Erweiterungsmethode

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;

namespace Test
{
    public static class StringHelper
    {
        private static CultureInfo ci = new CultureInfo("en-US");
        //Convert all first latter
        public static string ToTitleCase(this string str)
        {
            str = str.ToLower();
            var strArray = str.Split(' ');
            if (strArray.Length > 1)
            {
                strArray[0] = ci.TextInfo.ToTitleCase(strArray[0]);
                return string.Join(" ", strArray);
            }
            return ci.TextInfo.ToTitleCase(str);
        }
        public static string ToTitleCase(this string str, TitleCase tcase)
        {
            str = str.ToLower();
            switch (tcase)
            {
                case TitleCase.First:
                    var strArray = str.Split(' ');
                    if (strArray.Length > 1)
                    {
                        strArray[0] = ci.TextInfo.ToTitleCase(strArray[0]);
                        return string.Join(" ", strArray);
                    }
                    break;
                case TitleCase.All:
                    return ci.TextInfo.ToTitleCase(str);
                default:
                    break;
            }
            return ci.TextInfo.ToTitleCase(str);
        }
    }

    public enum TitleCase
    {
        First,
        All
    }
}
İbrahim Özbölük
quelle
Das Problem bei Ihrer Lösung ist, dass "Rotes Haus" in "Rotes Haus" und nicht in "Rotes Haus" umgewandelt wird, wie es in der Frage gestellt wurde.
Vadim
3
@Tacttin Es wird funktionieren, aber der folgende Code ist einfacher zu lesen und bietet eine bessere Leistung. Char.ToUpper (text [0]) + ((text.Length> 1)? Text.Substring (1) .ToLower (): string.Empty) ;; Sie können mehr lesen @ vkreynin.wordpress.com/2013/10/09/…
Vadim
1
Ich mag diese Lösung nicht, weil sie zwei ganz unterschiedliche Situationen zu einer langwierigen Methode kombiniert. Ich sehe auch keinen konzeptionellen Nutzen. Und die Implementierung, nur den ersten Buchstaben groß zu schreiben, ist lächerlich. Wenn Sie den ersten Buchstaben groß schreiben möchten, besteht die offensichtliche Implementierung darin , nur den ersten Buchstaben groß zu schreiben (ToUpper) . Stattdessen hätte ich zwei getrennte Methoden. FirstLetterToUpperin Equisos Antwort (oder in Guillernets neuerer Antwort) und ToTitleCasehier, jedoch ohne den zweiten Parameter. Dann brauche ich nicht enum TitleCase.
ToolmakerSteve
31

Für den ersten Buchstaben mit Fehlerprüfung:

public string CapitalizeFirstLetter(string s)
{
    if (String.IsNullOrEmpty(s))
        return s;
    if (s.Length == 1)
        return s.ToUpper();
    return s.Remove(1).ToUpper() + s.Substring(1);
}

Und hier ist das gleiche wie eine praktische Erweiterung

public static string CapitalizeFirstLetter(this string s)
    {
    if (String.IsNullOrEmpty(s)) return s;
    if (s.Length == 1) return s.ToUpper();
    return s.Remove(1).ToUpper() + s.Substring(1);
    }
Kobi
quelle
Sauberer Ansatz. Vielen Dank!
Philippe
11
public static string ToInvarianTitleCase(this string self)
{
    if (string.IsNullOrWhiteSpace(self))
    {
        return self;
    }

    return CultureInfo.InvariantCulture.TextInfo.ToTitleCase(self);
}
Big T.
quelle
6

Wenn die Leistung / Speichernutzung ein Problem darstellt, erstellt dieser nur einen (1) StringBuilder und einen (1) neuen String mit der gleichen Größe wie der Original-String.

public static string ToUpperFirst(this string str) {
  if( !string.IsNullOrEmpty( str ) ) {
    StringBuilder sb = new StringBuilder(str);
    sb[0] = char.ToUpper(sb[0]);

    return sb.ToString();

  } else return str;
}
Daniel Halan
quelle
3
Dies könnte mit einem einfachen char[]statt mit der gesamten Infrastruktur eines StringBuilderWraps geschehen . Anstatt new StringBuilder(str), Verwendung str.ToCharArray(), und statt sb.ToString(), Verwendung new string(charArray). StringBuilderemuliert die Art der Indizierung, die ein Zeichenarray nativ verfügbar macht, sodass die tatsächliche .ToUpperZeile im Wesentlichen dieselbe sein kann. :-)
Jonathan Gilbert
Darren (ein Jahr später) zeigt , wie dies zu tun mit ToCharArray, wie @JonathanGilbert vorgeschlagen
ToolmakerSteve
6

Schnellste Methode.

  private string Capitalize(string s){
        if (string.IsNullOrEmpty(s))
        {
            return string.Empty;
        }
        char[] a = s.ToCharArray();
        a[0] = char.ToUpper(a[0]);
        return new string(a);
}

Tests zeigen die nächsten Ergebnisse (Zeichenfolge mit 10000000 Symbolen als Eingabe): Testergebnisse

Александр Иванов
quelle
1
Ich empfehle, sParameter zurückzugeben, wenn sie null oder leer sind.
MatrixRonny
4

Versuche dies:

static public string UpperCaseFirstCharacter(this string text) {
    return Regex.Replace(text, "^[a-z]", m => m.Value.ToUpper());
}
JoelFan
quelle
2
oder vielleicht eine andere Zeichenklasse (dh alphanumerisch \ w), so dass die Funktion Unicode-
fähig
@ DmitryLedentsov- Die C # -Stringklasse basiert auf UTF-16-Zeichen. String-Klasse "Repräsentiert Text als Folge von UTF-16-Codeeinheiten."
ToolmakerSteve
4

Wenn Sie sich nur dafür interessieren, dass der erste Buchstabe groß geschrieben wird und der Rest der Zeichenfolge keine Rolle spielt, können Sie einfach das erste Zeichen auswählen, es in Großbuchstaben schreiben und es mit dem Rest der Zeichenfolge ohne das ursprüngliche erste Zeichen verketten.

String word ="red house";
word = word[0].ToString().ToUpper() + word.Substring(1, word.length -1);
//result: word = "Red house"

Wir müssen das erste Zeichen ToString () konvertieren, da wir es als Char-Array lesen und der Char-Typ keine ToUpper () -Methode hat.

Víctor García
quelle
3

Hier ist eine Möglichkeit, dies als Erweiterungsmethode zu tun:

static public string UpperCaseFirstCharacter(this string text)
{
    if (!string.IsNullOrEmpty(text))
    {
        return string.Format(
            "{0}{1}",
            text.Substring(0, 1).ToUpper(),
            text.Substring(1));
    }

    return text;
}

Kann dann wie folgt aufgerufen werden:

//yields "This is Brian's test.":
"this is Brian's test.".UpperCaseFirstCharacter(); 

Und hier sind einige Unit-Tests dafür:

[Test]
public void UpperCaseFirstCharacter_ZeroLength_ReturnsOriginal()
{
    string orig = "";
    string result = orig.UpperCaseFirstCharacter();

    Assert.AreEqual(orig, result);
}

[Test]
public void UpperCaseFirstCharacter_SingleCharacter_ReturnsCapital()
{
    string orig = "c";
    string result = orig.UpperCaseFirstCharacter();

    Assert.AreEqual("C", result);
}

[Test]
public void UpperCaseFirstCharacter_StandardInput_CapitalizeOnlyFirstLetter()
{
    string orig = "this is Brian's test.";
    string result = orig.UpperCaseFirstCharacter();

    Assert.AreEqual("This is Brian's test.", result);
}
bingles
quelle
1
string.Formatist übertrieben; einfach tun text.Substring(0, 1).ToUpper() + text.Substring(1).
ToolmakerSteve
3

Da ich zufällig auch daran gearbeitet habe und mich nach Ideen umgesehen habe, ist dies die Lösung, zu der ich gekommen bin. Es verwendet LINQ und kann den ersten Buchstaben einer Zeichenfolge groß schreiben, auch wenn das erste Vorkommen kein Buchstabe ist. Hier ist die Erweiterungsmethode, die ich am Ende gemacht habe.

public static string CaptalizeFirstLetter(this string data)
{
    var chars = data.ToCharArray();

    // Find the Index of the first letter
    var charac = data.First(char.IsLetter);
    var i = data.IndexOf(charac);

    // capitalize that letter
    chars[i] = char.ToUpper(chars[i]);

    return new string(chars);
}

Ich bin sicher, es gibt eine Möglichkeit, dies ein wenig zu optimieren oder zu bereinigen.

CAOakley
quelle
3

Ich habe hier etwas gefunden http://www.dotnetperls.com/uppercase-first-letter :

static string UppercaseFirst(string s)
{
// Check for empty string.
if (string.IsNullOrEmpty(s))
{
    return string.Empty;
}
// Return char and concat substring.
return char.ToUpper(s[0]) + s.Substring(1);
}

vielleicht hilft das!!

Mohammed Zameer
quelle
Wie ist dies eine Verbesserung gegenüber der Antwort von Equiso vor 4 Jahren?
ToolmakerSteve
3

Überprüfen Sie, ob die Zeichenfolge nicht null ist, und konvertieren Sie das erste Zeichen in Großbuchstaben und den Rest in Kleinbuchstaben:

public static string FirstCharToUpper(string str)
{
    return str?.First().ToString().ToUpper() + str?.Substring(1).ToLower();
}
Entwickler
quelle
Vielen Dank für die kleine Lösung anstelle weniger Codezeilen nur für ein Zeichenfolgenwort!
Imran Faruqi
2

Dies wird es tun, obwohl es auch sicherstellen wird, dass es keine fehlerhaften Großbuchstaben gibt, die nicht am Anfang des Wortes stehen.

public string(string s)
{
System.Globalization.CultureInfo c = new System.Globalization.CultureInfo("en-us", false)
System.Globalization.TextInfo t = c.TextInfo;

return t.ToTitleCase(s);
}
Jeff Hornby
quelle
2
Benötigt eine sNullprüfung vor dem Aufruf von ToTitleCase.
Taras Alenin
@ CarlosMuñoz tlhIngan Hol hat kein Buchstabengehäuse in seinem Skript. :-)
Jonathan Gilbert
2

Hier scheint es viel Komplexität zu geben, wenn Sie nur Folgendes benötigen:

    /// <summary>
    /// Returns the input string with the first character converted to uppercase if a letter
    /// </summary>
    /// <remarks>Null input returns null</remarks>
    public static string FirstLetterToUpperCase(this string s)
    {
        if (string.IsNullOrWhiteSpace(s))
            return s;

        return char.ToUpper(s[0]) + s.Substring(1);
    }

Bemerkenswerte Punkte:

  1. Es ist eine Erweiterungsmethode.

  2. Wenn die Eingabe null, leer oder Leerzeichen ist, wird die Eingabe unverändert zurückgegeben.

  3. String.IsNullOrWhiteSpace wurde mit .NET Framework 4 eingeführt. Dies funktioniert nicht mit älteren Frameworks.

Stephen Kennedy
quelle
1
Ich sehe nicht, wie dies eine Verbesserung gegenüber der ursprünglich akzeptierten Antwort von vor vier Jahren ist. Tatsächlich ist es inkonsistent (harmlos, aber vier Jahre zu spät, ich habe hohe Standards für eine neue Antwort, die Vorteile hinzufügt): Der einzige Vorteil der Verwendung der neueren IsNullOrWhiteSpaceanstelle von IsNullOrEmptyist, wenn Sie die ersten Nicht- Antworten finden und ändern. Leerraum . Aber Sie tun es nicht - Sie operieren immer weiter s[0]. Es ist also sinnlos [sowohl semantisch als auch leistungsmäßig] zu verwenden IsNullOrWhiteSpace.
ToolmakerSteve
... warum IsNullOrWhiteSpacemich diese Verwendung von beunruhigt, ist, dass ein unvorsichtiger Leser denken könnte: "Er hat nach Leerzeichen gesucht, sodass der folgende Code einen Buchstaben wirklich findet und ändert, selbst wenn ihm Leerzeichen vorangestellt sind." Da Ihr Code einen "ersten" Buchstaben mit Leerzeichen nicht ändern IsNullOrWhiteSpacekann , kann die Verwendung nur einen Leser irreführen .
ToolmakerSteve
... oops, ich meine nicht die akzeptierte Antwort, ich meine Equisos Antwort aus dem gleichen Zeitraum.
ToolmakerSteve
1
string emp="TENDULKAR";
string output;
output=emp.First().ToString().ToUpper() + String.Join("", emp.Skip(1)).ToLower();
Shailesh
quelle
Warum ToLower () am Schwanz?. Es sind keine anderen Buchstaben als der erste erforderlich.
Carlos Muñoz
StringDies kann alles sein, was Upperoder Lower.so ist es eine generische Lösung für alle Zeichenfolgen.
Shailesh
Warum Joinstatt emp.First().ToString().ToUpper() + emp.Substring(1);? Müssen wahrscheinlich auch defensiver sein : output = string.IsNullOrEmpty(emp) ? string.Empty : [...]. Außerdem, fwiw, stimme @ CarlosMuñoz zu - du brauchst das nicht ToLower()für die Frage des OP.
Ruffin
@ ruffin -> using Substring ist auch ein guter Schreibstil für Code. Ich stimme Ihrer Lösung zum Trimmen eines Codes zu, aber in diesem Fall ist das Schreiben von a eine ToLower()gute Programmierpraxis. stringkann alles sein UpperFalls oder LowerFall von Benutzereingaben abhängt, gebe ich eine generische Lösung.
Shailesh
@Shailesh - In der Frage wurde jedoch nicht verlangt, dass nur der erste Buchstabe ein Großbuchstabe ist. Es wurde darum gebeten, den ersten Buchstaben in eine Hauptstadt umzuwandeln. Ohne weitere Klarstellung durch den Autor ist die natürlichste Annahme, dass der Rest der Zeichenfolge unverändert bleibt. Da Sie drei Jahre später antworten , gehen Sie bitte davon aus, dass die akzeptierte Antwort den Anforderungen des Fragestellers entspricht. Geben Sie eine andere Antwort nur, wenn es einen technischen Grund gibt, dies anders zu tun.
ToolmakerSteve
1

Ich wollte eine "MAXIMALE LEISTUNG" -Antwort geben. In meinen Augen erfasst eine Antwort mit "MAXIMAL PERFORMANCE" alle Szenarien und liefert die Antwort auf die Frage, die diese Szenarien berücksichtigt. Also, hier ist meine Antwort. Mit diesen Gründen:

  1. IsNullOrWhiteSpace berücksichtigt Zeichenfolgen, die nur Leerzeichen oder null / leer sind.
  2. .Trim () entfernt Leerzeichen von der Vorder- und Rückseite der Zeichenfolge.
  3. .First () nimmt das erste Zeichen einer ienumerable (oder Zeichenfolge).
  4. Wir sollten prüfen, ob es sich um einen Buchstaben handelt, der in Großbuchstaben geschrieben werden kann / sollte.
  5. Wir fügen dann den Rest der Zeichenfolge nur hinzu, wenn die Länge angibt, dass wir sollten.
  6. Mit .Net Best Practice sollten wir eine Kultur unter System.Globalization.CultureInfo bereitstellen.
  7. Wenn Sie sie als optionale Parameter angeben, kann diese Methode vollständig wiederverwendet werden, ohne jedes Mal die ausgewählte Kultur eingeben zu müssen.

    public static string capString(string instring, string culture = "en-US", bool useSystem = false)
    {
        string outstring;
        if (String.IsNullOrWhiteSpace(instring))
        {
            return "";
        }
        instring = instring.Trim();
        char thisletter = instring.First();
        if (!char.IsLetter(thisletter))
        {
            return instring;   
        }
        outstring = thisletter.ToString().ToUpper(new CultureInfo(culture, useSystem));
        if (instring.Length > 1)
        {
            outstring += instring.Substring(1);
        }
        return outstring;
    }
Patrick Knott
quelle
2
Während dies die meisten Fälle abdeckt, wäre es nicht ziemlich langsam, wenn man bedenkt, wie viele Zeichenfolgen bei jeder Operation erstellt werden? Hier wird eine Menge Zeichenfolgen zugewiesen. Vorzugsweise würde es einmal und nur einmal zugewiesen.
Douglas Gaskell
1

Kürzlich hatte ich eine ähnliche Anforderung und erinnerte mich, dass die LINQ-Funktion Select () einen Index bereitstellt:

string input;
string output;

input = "red house";
output = String.Concat(input.Select((currentChar, index) => index == 0 ? Char.ToUpper(currentChar) : currentChar));
//output = "Red house"

Da ich das sehr oft brauche, habe ich eine Erweiterungsmethode für den String-Typ erstellt:

public static class StringExtensions
{
    public static string FirstLetterToUpper(this string input)
    {
        if (string.IsNullOrEmpty(input))
            return string.Empty;
        return String.Concat(input.Select((currentChar, index) => index == 0 ? Char.ToUpper(currentChar) : currentChar));
    }
}

Bitte beachten Sie, dass nur der erste Buchstabe in Großbuchstaben umgewandelt wird - alle verbleibenden Zeichen werden nicht berührt. Wenn die anderen Zeichen in Kleinbuchstaben geschrieben werden müssen, können Sie auch Char.ToLower (currentChar) für Index> 0 oder ToLower () für die gesamte Zeichenfolge aufrufen.

In Bezug auf die Leistung habe ich den Code mit der Lösung von Darren verglichen. Auf meinem Computer ist Darrens Code ungefähr zweimal schneller, was keine Überraschung ist, da er nur den ersten Buchstaben innerhalb eines char-Arrays direkt bearbeitet. Ich schlage vor, Sie nehmen Darrens Code, wenn Sie die schnellste verfügbare Lösung benötigen. Wenn Sie auch andere Zeichenfolgenmanipulationen integrieren möchten, kann es praktisch sein, die Ausdruckskraft einer Lambda-Funktion zu haben, die die Zeichen der Eingabezeichenfolge berührt - Sie können diese Funktion leicht erweitern -, daher lasse ich diese Lösung hier.

Grimm
quelle
Ich habe mich gefragt, wie ich dieses Problem lösen soll, habe meine eigene Lösung ausgearbeitet und bin dann zurückgekommen, um sie zu veröffentlichen, nur um festzustellen, dass Sie genau die gleiche Lösung gefunden haben, die ich bereits hatte. +1 für dich!
BlueFuzzyThing
Vielen Dank.
Grimm
1

Ich denke, die folgende Methode ist die beste Lösung

    class Program
{
    static string UppercaseWords(string value)
    {
        char[] array = value.ToCharArray();
        // Handle the first letter in the string.
        if (array.Length >= 1)
        {
            if (char.IsLower(array[0]))
            {
                array[0] = char.ToUpper(array[0]);
            }
        }
        // Scan through the letters, checking for spaces.
        // ... Uppercase the lowercase letters following spaces.
        for (int i = 1; i < array.Length; i++)
        {
            if (array[i - 1] == ' ')
            {
                if (char.IsLower(array[i]))
                {
                    array[i] = char.ToUpper(array[i]);
                }
            }
        }
        return new string(array);
    }

    static void Main()
    {
        // Uppercase words in these strings.
        const string value1 = "something in the way";
        const string value2 = "dot net PERLS";
        const string value3 = "String_two;three";
        const string value4 = " sam";
        // ... Compute the uppercase strings.
        Console.WriteLine(UppercaseWords(value1));
        Console.WriteLine(UppercaseWords(value2));
        Console.WriteLine(UppercaseWords(value3));
        Console.WriteLine(UppercaseWords(value4));
    }
}

Output

Something In The Way
Dot Net PERLS
String_two;three
 Sam

ref

D.JCode
quelle
1

Da es bei dieser Frage um die Maximierung der Leistung geht, habe ich Darrens Version für die Verwendung von Spans übernommen, wodurch der Müll reduziert und die Geschwindigkeit um etwa 10% verbessert wird.

        /// <summary>
        /// Returns the input string with the first character converted to uppercase
        /// </summary>
        public static string ToUpperFirst(this string s)
        {
            if (string.IsNullOrEmpty(s))
                throw new ArgumentException("There is no first letter");

            Span<char> a = stackalloc char[s.Length];
            s.AsSpan(1).CopyTo(a.Slice(1));
            a[0] = char.ToUpper(s[0]);
            return new string(a);
        }

Performance

|  Method |      Data |      Mean |     Error |    StdDev |
|-------- |---------- |----------:|----------:|----------:|
|  Carlos |       red | 107.29 ns | 2.2401 ns | 3.9234 ns |
|  Darren |       red |  30.93 ns | 0.9228 ns | 0.8632 ns |
| Marcell |       red |  26.99 ns | 0.3902 ns | 0.3459 ns |
|  Carlos | red house | 106.78 ns | 1.9713 ns | 1.8439 ns |
|  Darren | red house |  32.49 ns | 0.4253 ns | 0.3978 ns |
| Marcell | red house |  27.37 ns | 0.3888 ns | 0.3637 ns |

Vollständiger Testcode

using System;
using System.Linq;

using BenchmarkDotNet.Attributes;

namespace CorePerformanceTest
{
    public class StringUpperTest
    {
        [Params("red", "red house")]
        public string Data;

        [Benchmark]
        public string Carlos() => Data.Carlos();

        [Benchmark]
        public string Darren() => Data.Darren();

        [Benchmark]
        public string Marcell() => Data.Marcell();
    }

    internal static class StringExtensions
    {
        public static string Carlos(this string input) =>
            input switch
            {
                null => throw new ArgumentNullException(nameof(input)),
                "" => throw new ArgumentException($"{nameof(input)} cannot be empty", nameof(input)),
                _ => input.First().ToString().ToUpper() + input.Substring(1)
            };

        public static string Darren(this string s)
        {
            if (string.IsNullOrEmpty(s))
                throw new ArgumentException("There is no first letter");

            char[] a = s.ToCharArray();
            a[0] = char.ToUpper(a[0]);
            return new string(a);
        }

        public static string Marcell(this string s)
        {
            if (string.IsNullOrEmpty(s))
                throw new ArgumentException("There is no first letter");

            Span<char> a = stackalloc char[s.Length];
            s.AsSpan(1).CopyTo(a.Slice(1));
            a[0] = char.ToUpper(s[0]);
            return new string(a);
        }
    }

}

Bearbeiten: Es gab einen Tippfehler anstelle von s [0], war ein [0] - dies führt dazu, dass der leere Wert a auf den zugewiesenen Bereich a übertragen wird.

Marcell Toth
quelle
0

Dadurch wird dieser erste Buchstabe und jeder Buchstabe nach einem Leerzeichen großgeschrieben und jeder andere Buchstabe in Kleinbuchstaben geschrieben.

public string CapitalizeFirstLetterAfterSpace(string input)
{
    System.Text.StringBuilder sb = new System.Text.StringBuilder(input);
    bool capitalizeNextLetter = true;
    for(int pos = 0; pos < sb.Length; pos++)
    {
        if(capitalizeNextLetter)
        {
            sb[pos]=System.Char.ToUpper(sb[pos]);
            capitalizeNextLetter = false;
        }
        else
        {
            sb[pos]=System.Char.ToLower(sb[pos]);
        }

        if(sb[pos]=' ')
        {
            capitalizeNextLetter=true;
        }
    }
}
thattolleyguy
quelle
1
Oder wenn Sie keine Codewände schreiben möchten - CultureInfo.CurrentCulture.TextInfo.ToTitleCase (theString); macht das gleiche.
Chev
Ja ... das wusste ich nicht :) Und aufgrund meiner riesigen Menge an Code tauchten die Antworten aller anderen auf, während ich noch tippte.
thattolleyguy
UPVOTED: 1) Ein kleiner Unterschied zwischen dieser Antwort und ToTitleCase besteht darin, dass diese Antwort Wörter, die alle Großbuchstaben sind, zu TitleCase zwingt, während ToTitleCase solche Wörter in Ruhe lässt (vorausgesetzt, es handelt sich möglicherweise um Akronyme). Dies kann oder kann nicht das sein, was gewünscht wird. Ein Vorteil eines solchen Codebeispiels besteht darin, dass es nach Wunsch geändert werden kann. 2) Dies behandelt andere Leerzeichen als '' nicht korrekt. sollte den Blindtest durch Leerraumtest ersetzen.
ToolmakerSteve
0

Verwenden Sie den folgenden Code:

string  strtest ="PRASHANT";
strtest.First().ToString().ToUpper() + strtest.Remove(0, 1).ToLower();
Prashant Banavali
quelle
Es ist für meinen Repräsentanten nicht einmal einen Punkt wert, diese Antwort, die Jahre später hinzugefügt wurde, herabzustimmen, was offensichtlich gleichbedeutend mit bereits vorhandenen Antworten ist. Wenn Sie einer Frage mit vielen Antworten eine neue Antwort hinzufügen möchten , erläutern Sie bitte, was Ihrer Meinung nach Ihrer Antwort überlegen ist oder unter welchen Umständen Ihre Antwort nützlicher wäre als andere Antworten. Sei genau.
ToolmakerSteve
0

Es scheint, als würde keine der hier angegebenen Lösungen einen Leerraum vor der Zeichenfolge behandeln.

Fügen Sie dies nur als Gedanken hinzu:

public static string SetFirstCharUpper2(string aValue, bool aIgonreLeadingSpaces = true)
{
    if (string.IsNullOrWhiteSpace(aValue))
        return aValue;

    string trimmed = aIgonreLeadingSpaces 
           ? aValue.TrimStart() 
           : aValue;

    return char.ToUpper(trimmed[0]) + trimmed.Substring(1);
}   

Es sollte behandelt werden this won't work on other answers(dieser Satz hat am Anfang ein Leerzeichen), und wenn Sie das Leerzeichen-Trimmen nicht mögen, übergeben Sie einfach einen falseals zweiten Parameter (oder ändern Sie die Standardeinstellung in falseund übergeben trueSie, wenn Sie mit Leerzeichen umgehen möchten).

Noctis
quelle
0

Der einfachste Weg, den ersten Brief zu kapitalisieren, ist:

1- Verwenden von Sytem.Globalization;

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

  myTI.ToTitleCase(textboxname.Text)

`

Saad Khalid
quelle
1
Diese Antwort ist im Wesentlichen identisch mit den Antworten, die Jahre zuvor gegeben wurden. Es fügt der Diskussion nichts hinzu.
ToolmakerSteve
Es ist auch falsch, genau wie der Kommentar im anderen, dies dreht jeden ersten Buchstaben in allen Worten Kapital nicht dh rotes Haus statt rotes Haus.
DeadlyChambers
0

Die folgende Funktion ist in jeder Hinsicht korrekt:

static string UppercaseWords(string value)
{
    char[] array = value.ToCharArray();
    // Handle the first letter in the string.
    if (array.Length >= 1)
    {
        if (char.IsLower(array[0]))
        {
            array[0] = char.ToUpper(array[0]);
        }
    }
    // Scan through the letters, checking for spaces.
    // ... Uppercase the lowercase letters following spaces.
    for (int i = 1; i < array.Length; i++)
    {
        if (array[i - 1] == ' ')
        {
            if (char.IsLower(array[i]))
            {
                array[i] = char.ToUpper(array[i]);
            }
        }
    }
    return new string(array);
}

Das habe ich hier gefunden


quelle
Warum? Warum noch eine Antwort hinzufügen , wenn es bereits so viele Antworten gibt, die ähnlich erscheinen? Was ist falsch an all den vorhandenen Antworten, die Sie dazu veranlasst haben, eine weitere hinzuzufügen?
ToolmakerSteve
Weil diese Answare in jeder Hinsicht korrekt ist. Immer mit der Ruhe.
Tut mir leid; Ich war unnötig hart. Ich werde mich an die Fakten halten: 1) Dies entspricht im Wesentlichen der Antwort von thattolleyguy vor sieben Jahren. 2) Dies hat den gleichen Fehler wie diese Antwort: Behandelt keine anderen Leerzeichen als Leerzeichen. 3) Dies beantwortet eine etwas andere Frage als OP. Verwenden Sie eine Antwort wie diese, wenn alle Wörter in Großbuchstaben geschrieben werden sollen. 4) Normalerweise ist es einfacher, TitleInfo.ToTitleCase zu verwenden, um dies zu erreichen. (Andererseits ist ein Vorteil des Codebeispiels, dass es nach Wunsch angepasst werden kann.)
ToolmakerSteve
Ich korrigiere mich selbst: Dies ist etwas anderes als der Ansatz von thattolleyguy: Es bleiben unberührte Buchstaben übrig, die nicht der erste Buchstabe des Wortes sind. Stattdessen ist es ein Duplikat von Zamoldars Antwort . Günstigerweise ein großes Lob an Darian für die Angabe des Links zur Quelle - es scheint zamoldar plagiiert zu sein, ohne Anerkennung zu geben. Aufgrund der Bereitstellung dieses Quelllinks und damit der Verbesserung der Diskussion stimme ich dieser Antwort trotz meiner Kritik zu.
ToolmakerSteve
1
Darian, zwei Verbesserungen, die vorgenommen werden könnten: 1) Verwenden Sie char.IsWhiteSpace( array[ i -1 ] )stattdessen anstelle von .. == ' ', um alle Leerzeichen zu verarbeiten. 2) Entfernen Sie die beiden Stellen, die dies tun if (char.isLower(..))- sie haben keinen Zweck. ToUppertut einfach nichts, wenn ein Zeichen nicht in Kleinbuchstaben geschrieben ist.
ToolmakerSteve
0

Wenn Sie die obige Frage von Carlos erweitern und mehrere Sätze groß schreiben möchten, können Sie diesen Code verwenden:

    /// <summary>
    /// Capitalize first letter of every sentence. 
    /// </summary>
    /// <param name="inputSting"></param>
    /// <returns></returns>
    public string CapitalizeSentences (string inputSting)
    {
        string result = string.Empty;
        if (!string.IsNullOrEmpty(inputSting))
        {
            string[] sentences = inputSting.Split('.');

            foreach (string sentence in sentences)
            {
                result += string.Format ("{0}{1}.", sentence.First().ToString().ToUpper(), sentence.Substring(1)); 
            }
        }

        return result; 
    }
Zamir
quelle
0

Mögliche Lösung zur Lösung Ihres Problems.

   public static string FirstToUpper(this string lowerWord)
   {
       if (string.IsNullOrWhiteSpace(lowerWord) || string.IsNullOrEmpty(lowerWord))
            return lowerWord;
       return new StringBuilder(lowerWord.Substring(0, 1).ToUpper())
                 .Append(lowerWord.Substring(1))
                 .ToString();
   }
sayah imad
quelle