BestPractice - Transformiert das erste Zeichen einer Zeichenfolge in Kleinbuchstaben

136

Ich hätte gerne eine Methode, die das erste Zeichen einer Zeichenfolge in Kleinbuchstaben umwandelt.

Meine Ansätze:

1.

public static string ReplaceFirstCharacterToLowerVariant(string name)
{
    return String.Format("{0}{1}", name.First().ToString().ToLowerInvariant(), name.Substring(1));
}

2.

public static IEnumerable<char> FirstLetterToLowerCase(string value)
{
    var firstChar = (byte)value.First();
    return string.Format("{0}{1}", (char)(firstChar + 32), value.Substring(1));
}

Was wäre Ihr Ansatz?

Rookian
quelle

Antworten:

239

Ich würde einfache Verkettung verwenden:

Char.ToLowerInvariant(name[0]) + name.Substring(1)

Die erste Lösung ist nicht optimiert, da sie string.Formatlangsam ist und Sie sie nicht benötigen, wenn Sie ein Format haben, das sich nie ändern wird. Außerdem wird eine zusätzliche Zeichenfolge generiert, um den Buchstaben in Kleinbuchstaben umzuwandeln, die nicht benötigt wird.

Der Ansatz mit "+ 32" ist hässlich / nicht wartbar, da Kenntnisse über ASCII-Zeichenwert-Offsets erforderlich sind. Es wird auch eine falsche Ausgabe mit Unicode-Daten und ASCII-Symbolzeichen generiert.

onof
quelle
4
Ich würde es tun:char.ToLower(name[0]).ToString() + name.Substring(1)
Andrey
7
@Rookian: Der +Operator ist langsam, wenn Sie viele Zeichenfolgen verketten. In diesem Fall StringBuilderwürde a viel besser abschneiden. Ist +jedoch viel schneller als string.Format. Verwenden Sie Letzteres, wenn Sie tatsächlich etwas formatieren müssen (z. B. die Anzeige von Ganzzahlen, Doppelwerten oder Datumsangaben).
Dirk Vollmar
6
@ 0x03: Es ist nur langsam, wenn Sie viele Zeichenfolgen iterativ verketten. Wenn Sie sie alle in einer einzigen Operation verketten, ist der +Operator überhaupt nicht langsam, da der Compiler daraus eine macht String.Concat(ist jedoch String.Joinschneller alsString.Concat aus irgendeinem dummen Grund).
Thorarin
2
Eine schnellere Methode ist folgende: public static string ToFirstLetterLower (Zeichenfolgentext) {var charArray = text.ToCharArray (); charArray [0] = char.ToLower (charArray [0]); neuen String zurückgeben (charArray); }
Matteo Migliore
2
Ich habe die Erweiterung public static string ToLowerFirst(this string source) { if (string.IsNullOrWhiteSpace(source)) return source; var charArray = source.ToCharArray(); charArray[0] = char.ToLower(charArray[0]); return new string(charArray); } basierend auf dem Kommentar von @ MatteoMigliore verwendet.
KregHEk
64

Je nach Situation kann eine kleine defensive Programmierung wünschenswert sein:

public static string FirstCharacterToLower(string str)
{
    if (String.IsNullOrEmpty(str) || Char.IsLower(str, 0))
        return str;

    return Char.ToLowerInvariant(str[0]) + str.Substring(1);
}

Die ifAnweisung verhindert auch, dass eine neue Zeichenfolge erstellt wird, wenn sie ohnehin nicht geändert wird. Möglicherweise möchten Sie, dass die Methode stattdessen bei der Null-Eingabe fehlschlägt, und eine auslösen ArgumentNullException.

Wie die Leute bereits erwähnt haben, ist die Verwendung String.Formatdafür übertrieben.

Thorarin
quelle
Korrigieren Sie mich, wenn ich falsch liege, aber str.Substring (1) gibt das Symbol an Position 1 zurück, da die Anzahl für diese Methode nicht angegeben ist. Sie haben also char [0] in Kleinbuchstaben + das Zeichen an Position 1. Daher habe ich es vorgezogen, ein Zeichen ab dem ersten Zeichen in der Zeichenfolge zu entfernen. Das Ergebnis ist die Zeichenfolge ohne Anfangsbuchstaben. Dann werde ich diesen String zum ersten
Zeichen
3
@ B-Rain: Betrachten Sie sich als korrigiert: msdn.microsoft.com/en-us/library/hxthx5h6%28VS.90%29.aspx
Thorarin
7

Nur für den Fall, dass es jemandem hilft, der zufällig über diese Antwort stolpert.

Ich denke, dies wäre am besten als Erweiterungsmethode, dann können Sie es mit yourString.FirstCharacterToLower () aufrufen;

public static class StringExtensions
{
    public static string FirstCharacterToLower(this string str)
    {
        if (String.IsNullOrEmpty(str) || Char.IsLower(str, 0))
        {
            return str;
        }

        return Char.ToLowerInvariant(str[0]) + str.Substring(1);
    }
}
Carlcheel
quelle
3

Meins ist

if (!string.IsNullOrEmpty (val) && val.Length > 0)
{
    return val[0].ToString().ToLowerInvariant() + val.Remove (0,1);   
}
Fedotoves
quelle
3
Ich bin neugierig, warum das val.Remove? Scheint mir ein wenig kontraintuitiv zu sein.
Thorarin
@ Thorarin offensichtlich, weil Sie das erste Zeichen entfernen möchten (weil Sie die Kleinbuchstabenversion vorne hinzufügen)
Riki
2

Ich mag die akzeptierte Antwort, aber neben der Überprüfung string.IsNullOrEmptywürde ich auch prüfen, ob Char.IsLower(name[1])es sich um eine Abkürzung handelt. Zum Beispiel möchten Sie nicht, dass "AIDS" zu "AIDS" wird.

Slobodan Savkovic
quelle
7
IMO dies liegt in der Verantwortung des Anrufers
am
1

Die schnellste Lösung, die ich kenne, ohne c # zu missbrauchen:

public static string LowerCaseFirstLetter(string value)
{
    if (value?.Length > 0)
    {
        var letters = value.ToCharArray();
        letters[0] = char.ToLowerInvariant(letters[0]);
        return new string(letters);
    }
    return value;
}
Rjz
quelle
0

Kombinierte ein paar und machte es zu einer verkettbaren Erweiterung. Kurzschluss bei Leerzeichen und Nichtbuchstaben hinzugefügt.

public static string FirstLower(this string input) => 
    (!string.IsNullOrWhiteSpace(input) && input.Length > 0 
        && char.IsLetter(input[0]) && !char.IsLower(input[0]))
    ? input[0].ToString().ToLowerInvariant() + input.Remove(0, 1) : input;
Randy Buchholz
quelle
0

Dies ist eine kleine Erweiterungsmethode, die die neueste Syntax und korrekte Validierungen verwendet

public static class StringExtensions
{
    public static string FirstCharToLower(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().ToLower() + input.Substring(1);
        }
    }
}
Carlos Muñoz
quelle
1
Ich bin mir nicht sicher, ob das Auslösen einer Ausnahme die beste Lösung wäre. Ist die Zeichenfolge null oder leer, geben Sie einfach die null oder leere Zeichenfolge zurück.
R. de Veen
Wenn String null oder leer ist, ist die Operation nicht sinnvoll, da kein erstes Zeichen in Kleinbuchstaben geändert werden kann.
Carlos Muñoz
0

Benutze das:

string newName= name[0].ToString().ToLower() + name.Substring(1);
hojjat.mi
quelle
-3

Es ist besser zu verwenden, String.Concatals String.Formatwenn Sie wissen, dass das Format keine Daten ändert und nur eine Verkettung erwünscht ist.

Konstantin Isaev
quelle