Welche Methode in der String-Klasse gibt nur die ersten N Zeichen zurück?

184

Ich möchte eine Erweiterungsmethode in die StringKlasse schreiben N, damit nur die ersten NZeichen angezeigt werden , wenn die Eingabezeichenfolge länger als die angegebene Länge ist .

So sieht es aus:

public static string TruncateLongString(this string str, int maxLength)
{
    if (str.Length <= maxLength)
        return str;
    else
        //return the first maxLength characters                
}

Mit welcher String.*()Methode kann ich nur die ersten NZeichen von erhalten str?

Richard77
quelle

Antworten:

374
public static string TruncateLongString(this string str, int maxLength)
{
    if (string.IsNullOrEmpty(str))
        return str;
    return str.Substring(0, Math.Min(str.Length, maxLength));
}
Paul Ruane
quelle
6
Wird die Math.Min benötigt? Ich dachte, Substring wusste, dass wenn der zweite Parameter größer als die Länge war, er nur die Länge einsteckte?
Martin
12
Ich glaube es ist: System.String.InternalSubStringWithChecks würde ArgumentOutOfRange auslösen.
Paul Ruane
2
@ Martin: nicht das ich sehen kann, startIndex > (this.Length - length)wirft ein ArgumentOutOfRangeException.
user7116
2
Ich wollte vorschlagen, zu prüfen, ob Math.Min(str.Length, maxLength) == str.Lengthfür den Fall, dass Sie eine unnötige Zeichenfolge erstellen, um "die ersten str.Length-Zeichen von str" zurückzugeben, aber Substring überprüft dies für Sie und nur, return thiswenn Sie nach der gesamten Zeichenfolge gefragt haben.
Stevemegson
2
Wenn Sie möchten, dass die Erweiterungsmethode für potenziell null Zeichenfolgen funktioniert ... return str? .Substring (0, Math.Min (str.Length, maxLength));
Ihake
62
string truncatedToNLength = new string(s.Take(n).ToArray());  

Diese Lösung hat den winzigen Vorteil, dass wenn n größer als s.Length ist, sie immer noch das Richtige tut.

Matt Greer
quelle
9
Ja, aber mit Linq einen String abschneiden? Beachten Sie jedoch, dass dies bei mehrmaliger Verwendung, z. B. in einer Schleife, sehr schlecht funktioniert. Tun Sie dies nicht aus Gewohnheit
ErikE
31

Sie können LINQ str.Take(n)oder verwenden str.SubString(0, n), wobei letzteres eine ArgumentOutOfRangeExceptionAusnahme für auslöst n > str.Length.

Daran , dass die LINQ - Version eine gibt IEnumerable<char>, so würde man konvertieren das IEnumerable<char>zu string: new string(s.Take(n).ToArray()).

theburningmonk
quelle
10
Verwenden Sie Linq nicht zum Abschneiden von Zeichenfolgen. Das ist lächerlich.
ErikE
17

Immer wenn ich String-Manipulationen in C # durchführen muss, vermisse ich die guten alten Leftund RightFunktionen von Visual Basic, die viel einfacher zu verwenden sind als Substring.

In den meisten meiner C # -Projekte erstelle ich Erweiterungsmethoden für sie:

public static class StringExtensions
{
    public static string Left(this string str, int length)
    {
        return str.Substring(0, Math.Min(length, str.Length));
    }

    public static string Right(this string str, int length)
    {
        return str.Substring(str.Length - Math.Min(length, str.Length));
    }
}

Hinweis:
Der Math.MinTeil ist vorhanden, weil ein Substringausgelöst wird, ArgumentOutOfRangeExceptionwenn die Länge der Eingabezeichenfolge kleiner als die angeforderte Länge ist, wie bereits in einigen Kommentaren unter den vorherigen Antworten erwähnt.

Verwendung:

string longString = "Long String";

// returns "Long";
string left1 = longString.Left(4);

// returns "Long String";
string left2 = longString.Left(100);
Christian Specht
quelle
Ich mag das, aber wenn die Zeichenfolge kürzer als die angegebene Länge wäre, würde sie keine Leerzeichen anhängen. public static string Left(this string str, int length) { var Result = str.Substring(0, Math.Min(length, str.Length)); return (Result.Length < length) ? Result.PadRight(length) : Result; }
Grandizer
strmuss auf null überprüft werden
liviriniu
14

Einfach:

public static String Truncate(String input,int maxLength)
{
   if(input.Length > maxLength)
      return input.Substring(0,maxLength);
   return input;
}
Majid
quelle
7
public static string TruncateLongString(this string str, int maxLength)
{
    return str.Length <= maxLength ? str : str.Remove(maxLength);
}
kbrimington
quelle
1
Beachten Sie auch, dass Sie die Erweiterungsmethode auch null-sicher machen können, indem Sie die Bedingung instr == null || str.Length <= maxLength
kbrimington
6
Für alle, die sich fragen, ob es besser ist Removeoder nicht Substring, gibt es keinen Unterschied. Remove(maxLength)ruft nur Substring(0,maxLength)nach ein paar Grenzüberprüfungen an. Was Sie bevorzugen, hängt davon ab, ob Sie die Kürzung als "Nehmen Sie die ersten maxLength-Zeichen" oder "alles nach maxLength-Zeichen wegwerfen" betrachten. Natürlich ist es wirklich beides, also liegt es an dir.
Stevemegson
5

Wenn wir über Validierungen sprechen, warum wir nicht nach Null-String-Einträgen gesucht haben. Irgendwelche spezifischen Gründe?

Ich denke weiter unten helfen, da IsNullOrEmpty eine systemdefinierte Methode ist und ternäre Operatoren eine zyklomatische Komplexität = 1 haben, während if () {} else {} den Wert 2 hat.

    public static string Truncate(string input, int truncLength)
    {
        return (!String.IsNullOrEmpty(input) && input.Length >= truncLength)
                   ? input.Substring(0, truncLength)
                   : input;
    }
sunnytyra
quelle
Was ist ein Problem mit der zyklomatischen Komplexität 2?
Muflix
1

Ich habe dies in mein Projekt aufgenommen, nur weil die Wahrscheinlichkeit, dass es in Schleifen verwendet wird, in einem online gehosteten Projekt hoch ist, daher wollte ich keine Abstürze, wenn ich es verwalten könnte. Die Länge passt zu einer Spalte, die ich habe. Es ist C # 7

Nur eine Zeile:

 public static string SubStringN(this string Message, int Len = 499) => !String.IsNullOrEmpty(Message) ? (Message.Length >= Len ? Message.Substring(0, Len) : Message) : "";
Richard Griffiths
quelle
0

Die .NET-Teilstring-Methode ist mit Gefahren behaftet. Ich habe Erweiterungsmethoden entwickelt, die eine Vielzahl von Szenarien behandeln. Das Schöne ist, dass das ursprüngliche Verhalten beibehalten wird. Wenn Sie jedoch einen zusätzlichen "true" -Parameter hinzufügen, wird zur Behandlung der Ausnahme auf die Erweiterungsmethode zurückgegriffen und die logischsten Werte basierend auf Index und Länge zurückgegeben. Zum Beispiel, wenn die Länge negativ ist und rückwärts zählt. Sie können die Testergebnisse mit einer Vielzahl von Werten auf der Geige unter folgender Adresse anzeigen: https://dotnetfiddle.net/m1mSH9 . Auf diese Weise erhalten Sie eine klare Vorstellung davon, wie Teilzeichenfolgen aufgelöst werden.

Ich füge diese Methoden immer allen meinen Projekten hinzu und muss mich nie um das Brechen von Code kümmern, da sich etwas geändert hat und der Index ungültig ist. Unten ist der Code.

    public static String Substring(this String val, int startIndex, bool handleIndexException)
    {
        if (!handleIndexException)
        { //handleIndexException is false so call the base method
            return val.Substring(startIndex);
        }
        if (string.IsNullOrEmpty(val))
        {
            return val;
        }
        return val.Substring(startIndex < 0 ? 0 : startIndex > (val.Length - 1) ? val.Length : startIndex);
    }

    public static String Substring(this String val, int startIndex, int length, bool handleIndexException)
    {
        if (!handleIndexException)
        { //handleIndexException is false so call the base method
            return val.Substring(startIndex, length);
        }
        if (string.IsNullOrEmpty(val))
        {
            return val;
        }
        int newfrom, newlth, instrlength = val.Length;
        if (length < 0) //length is negative
        {
            newfrom = startIndex + length;
            newlth = -1 * length;
        }
        else //length is positive
        {
            newfrom = startIndex;
            newlth = length;
        }
        if (newfrom + newlth < 0 || newfrom > instrlength - 1)
        {
            return string.Empty;
        }
        if (newfrom < 0)
        {
            newlth = newfrom + newlth;
            newfrom = 0;
        }
        return val.Substring(newfrom, Math.Min(newlth, instrlength - newfrom));
    }

Ich habe bereits im Mai 2010 darüber gebloggt : http://jagdale.blogspot.com/2010/05/substring-extension-method-that-does.html

Vijay Jagdale
quelle
0

Teilweise aus Gründen der Zusammenfassung (ohne LINQ-Lösung) sind hier zwei Einzeiler aufgeführt, die sich mit der int maxLengthEinschränkung befassen , negative Werte zuzulassen, sowie mit dem Fall einer Nullzeichenfolge:

  1. Der SubstringWeg (aus Paul Ruanes Antwort ):
public static string Truncate(this string s, uint maxLength) =>
    s?.Substring(0, Math.Min(s.Length, (int)maxLength));
  1. Der RemoveWeg (aus Kbrimingtons Antwort ):
public static string Truncate(this string s, uint maxLength) =>
    s?.Length > maxLength ? s.Remove((int)maxLength) : s;
liviriniu
quelle
-1
substring(int startpos, int lenght);
Tokk
quelle
-4

string.Substring (0, n); // 0 - Startindex und n - Anzahl der Zeichen

Jagan
quelle
4
Im Gegensatz zur akzeptierten Antwort kann dies zu Indexfehlern außerhalb der Grenzen führen.
Servy