it-swarm.com.de

Wie schneide ich eine .NET-Zeichenfolge ab?

Ich möchte eine Zeichenfolge so abschneiden, dass ihre Länge nicht länger als ein bestimmter Wert ist. Ich schreibe in eine Datenbanktabelle und möchte sicherstellen, dass die von mir geschriebenen Werte der Einschränkung des Datentyps der Spalte entsprechen.

Zum Beispiel wäre es schön, wenn ich folgendes schreiben könnte:

string NormalizeLength(string value, int maxLength)
{
    return value.Substring(0, maxLength);
}

Leider löst dies eine Ausnahme aus, da maxLength im Allgemeinen die Grenzen der Zeichenfolge value überschreitet. Natürlich könnte ich eine Funktion wie die folgende schreiben, aber ich hatte gehofft, dass so etwas schon existiert.

string NormalizeLength(string value, int maxLength)
{
    return value.Length <= maxLength ? value : value.Substring(0, maxLength);
} 

Wo ist die schwer fassbare API, die diese Aufgabe ausführt? Ist dort eines?

340
Steve Guidi

Leider gibt es keine Truncate()-Methode für string. Sie müssen diese Art von Logik selbst schreiben. Sie können dies jedoch in eine Erweiterungsmethode packen, damit Sie es nicht überall kopieren müssen:

public static class StringExt
{
    public static string Truncate(this string value, int maxLength)
    {
        if (string.IsNullOrEmpty(value)) return value;
        return value.Length <= maxLength ? value : value.Substring(0, maxLength); 
    }
}

Jetzt können wir schreiben:

var someString = "...";
someString = someString.Truncate(2);
521
LBushkin

Anstelle des ternären Operators können Sie auch Math.min verwenden

public static class StringExt
{
    public static string Truncate( this string value, int maxLength )
    {
        if (string.IsNullOrEmpty(value)) { return value; }

        return value.Substring(0, Math.Min(value.Length, maxLength));
    }
}
105
CaffGeek

Ich dachte, ich würde meine Implementierung einbringen, da ich glaube, dass sie alle Fälle abdeckt, die von den anderen angesprochen wurden, und zwar auf eine präzise und lesbare Art und Weise.

public static string Truncate(this string value, int maxLength)
{
    if (!string.IsNullOrEmpty(value) && value.Length > maxLength)
    {
        return value.Substring(0, maxLength);
    }

    return value;
}

Diese Lösung baut hauptsächlich auf der Ray-Lösung auf und öffnet die Methode als Erweiterungsmethode, indem das Schlüsselwort this verwendet wird, genau wie LBushkin in seiner Lösung.

35
jpierson

In .NET 4.0 können Sie die Take-Methode verwenden:

string.Concat(myString.Take(maxLength));

Nicht auf Effizienz geprüft!

29
Dylan Nicholson

Sie könnten LINQ verwenden. Dadurch entfällt die Prüfung der Stringlänge. Zugegebenermaßen vielleicht nicht besonders effizient, aber es macht Spaß.

string result = string.Join("", value.Take(maxLength)); // .NET 4 Join

oder

string result = new string(value.Take(maxLength).ToArray());
28
tames

Weil Leistungstests Spaß machen: (mit linqpad Erweiterungsmethoden )

var val = string.Concat(Enumerable.Range(0, 50).Select(i => i % 10));

foreach(var limit in new[] { 10, 25, 44, 64 })
    new Perf<string> {
        { "newstring" + limit, n => new string(val.Take(limit).ToArray()) },
        { "concat" + limit, n => string.Concat(val.Take(limit)) },
        { "truncate" + limit, n => val.Substring(0, Math.Min(val.Length, limit)) },
        { "smart-trunc" + limit, n => val.Length <= limit ? val : val.Substring(0, limit) },
        { "stringbuilder" + limit, n => new StringBuilder(val, 0, Math.Min(val.Length, limit), limit).ToString() },
    }.Vs();

Die truncate-Methode war "wesentlich" schneller. #Mikrooptimierung

Früh

  • truncate10 5788 abgelaufene Ticks (0,5788 ms) [in Wiederholungen von 10.000 Wiederholungen, 5.788E-05 ms pro] 
  • smart-Trunc10 8206 Ticks verstrichen (0,8206 ms) [in Wiederholungen mit 10.000 Wiederholungen, 8.206E-05 ms pro] 
  • stringbuilder10 10557 verstrichene Ticks (1,0557 ms) [in Wiederholungen von 10.000 Wiederholungen, 0,00010557 ms pro] 
  • concat10 45495 Ticks verstrichen (4.5495 ms) [in Wiederholungen von 10.000 Wiederholungen, 0.00045495 ms pro] 
  • newstring10 72535 verstrichene Ticks (7,2535 ms) [in Wiederholungen mit 10.000 Wiederholungen, 0,00072535 ms per] 

Spät

  • truncate44 8835 Ticks verstrichen (0,8835 ms) [in Wiederholungen von 10.000 Wiederholungen, 8.835E-05 ms pro] 
  • stringbuilder44 13106 verstrichene Ticks (1.3106 ms) [in Wiederholungen von 10.000 Wiederholungen, 0.00013106 ms pro] 
  • smart-Trunc44 14821 verstrichene Ticks (1,4821 ms) [in Wiederholungen mit 10.000 Wiederholungen, 0,00014821 ms pro] 
  • newstring44 144324 verstrichene Ticks (14.4324 ms) [in Wiederholungen von 10.000 Wiederholungen, 0,00144324 ms pro] 
  • concat44 174610 abgelaufene Ticks (17,461 ms) [in Wiederholungen von 10.000 Wiederholungen, 0,0017461 ms pro] 

Zu lang

  • smart-trunc64 6944 Ticks verstrichen (0,6944 ms) [in Wiederholungen mit 10.000 Wiederholungen, 6,944E-05 ms pro] 
  • truncate64 7686 verstrichene Ticks (0,7686 ms) [in Wiederholungen von 10.000 Wiederholungen, 7,668E-05 ms pro] 
  • stringbuilder64 13314 verstrichene Ticks (1.3314 ms) [in Wiederholungen von 10.000 Wiederholungen, 0.00013314 ms per] 
  • newstring64 177481 verstrichene Ticks (17,7481 ms) [in Wiederholungen mit 10.000 Wiederholungen, 0,00177481 ms pro] 
  • concat64 241601 verstrichene Ticks (24.1601 ms) [in Wiederholungen von 10.000 Wiederholungen, 0,00241601 ms pro] 
20
drzaus

Das .NET Framework verfügt über eine API, um eine Zeichenfolge wie folgt abzuschneiden:

Microsoft.VisualBasic.Strings.Left(string, int);

In einer C # -App werden Sie jedoch wahrscheinlich lieber eine eigene Rolle verwenden, als eine Abhängigkeit von Microsoft.VisualBasic.dll zu übernehmen, deren Hauptzweck die Rückwärtskompatibilität ist.

11
Joe

Anscheinend hat noch niemand dies gepostet:

public static class StringExt
{
    public static string Truncate(this string s, int maxLength)
    {
        return s != null && s.Length > maxLength ? s.Substring(0, maxLength) : s;
    }
}

Wenn Sie den Operator && verwenden, ist er geringfügig besser als die akzeptierte Antwort.

10
Darren

Ich habe meine in einer Linie so gemacht

value = value.Length > 1000 ? value.Substring(0, 1000) : value;
8
SeanKPS

Eine ähnliche Variante mit dem Null-Ausbreitungsoperator von C # 6

public static string Truncate(this string value, int maxLength)
{
    return value?.Length <= maxLength ? value : value?.Substring(0, maxLength);
}

Bitte beachten Sie, dass wir im Wesentlichen prüfen, ob value hier zweimal null ist.

5
Jamie Rees

@CaffGeek nehmen und vereinfachen:

public static string Truncate(this string value, int maxLength)
    {
        return string.IsNullOrEmpty(value) ? value : value.Substring(0, Math.Min(value.Length, maxLength));
    }
4
Edwin Beltran

Beachten Sie, dass das Abschneiden einer Zeichenfolge nicht nur bedeutet, dass Sie eine Zeichenfolge nur mit einer bestimmten Länge schneiden, sondern dass Sie darauf achten, das Wort nicht zu teilen. 

zB Zeichenfolge: Dies ist eine Testzeichenfolge. 

Ich möchte es um 11 abschneiden. Wenn wir eine der oben angegebenen Methoden verwenden, ist das Ergebnis

das ist ein te

Das ist nicht das, was wir wollen

Die Methode, die ich verwende, ist möglicherweise nicht so perfekt, aber sie kann die meisten Situationen bewältigen

public string CutString(string source, int length)
{
        if (source== null || source.Length < length)
        {
            return source;
        }
        int nextSpace = source.LastIndexOf(" ", length);
        return string.Format("{0}...", input.Substring(0, (nextSpace > 0) ? nextSpace : length).Trim());
} 
4
Sen K. Mathew

Noch keine Truncate-Methode für C # -Strings im Jahr 2016. Aber - Verwenden der C # 6.0-Syntax:

public static class StringExtension
{
  public static string Truncate(this string s, int max) 
  { 
    return s?.Length > max ? s.Substring(0, max) : s ?? throw new ArgumentNullException(s); 
  }
}

Es wirkt wie ein Zauber:

"Truncate me".Truncate(8);
Result: "Truncate"
4
Tobias Schiele

Ich weiß, das ist eine alte Frage, aber hier ist eine schöne Lösung:

public static string Truncate(this string text, int maxLength, string suffix = "...")
{
    string str = text;
    if (maxLength > 0)
    {
        int length = maxLength - suffix.Length;
        if (length <= 0)
        {
            return str;
        }
        if ((text != null) && (text.Length > maxLength))
        {
            return (text.Substring(0, length).TrimEnd(new char[0]) + suffix);
        }
    }
    return str;
}

var myString = "hello world"
var myTruncatedString = myString.Truncate(4);

Rückkehr: Hallo ...

4
nologo

Warum nicht:

string NormalizeLength(string value, int maxLength)
{
    //check String.IsNullOrEmpty(value) and act on it. 
    return value.PadRight(maxLength).Substring(0, maxLength);
}

d. h., falls value.Length < maxLength Pad Leerzeichen bis zum Ende enthält oder den Überschuss abschneidet.

3
Sri

Nur für den Fall, dass es nicht genug Antworten gibt, hier ist meine :)

public static string Truncate(this string str, 
                              int totalLength, 
                              string truncationIndicator = "")
{
    if (string.IsNullOrEmpty(str) || str.Length < totalLength) 
        return str;

    return str.Substring(0, totalLength - truncationIndicator.Length) 
           + truncationIndicator;
}

benutzen:

"I use it like this".Truncate(5,"~")
3
K. R.

Eine andere Lösung:

return input.Substring(0, Math.Min(input.Length, maxLength));
2

Aus Gründen der (übermäßigen) Komplexität füge ich meine überladene Version hinzu, die die letzten 3 Zeichen durch einen Ellipsis-Wert in Bezug auf den Parameter maxLength ersetzt.

public static string Truncate(this string value, int maxLength, bool replaceTruncatedCharWithEllipsis = false)
{
    if (replaceTruncatedCharWithEllipsis && maxLength <= 3)
        throw new ArgumentOutOfRangeException("maxLength",
            "maxLength should be greater than three when replacing with an Ellipsis.");

    if (String.IsNullOrWhiteSpace(value)) 
        return String.Empty;

    if (replaceTruncatedCharWithEllipsis &&
        value.Length > maxLength)
    {
        return value.Substring(0, maxLength - 3) + "...";
    }

    return value.Substring(0, Math.Min(value.Length, maxLength)); 
}
2
SoftDev

Meine zwei Cent mit Beispiellänge von 30:

  var truncatedInput = string.IsNullOrEmpty(input) ? 
      string.Empty : 
      input.Substring(0, Math.Min(input.Length, 30));
1
Ognyan Dimitrov

Ich weiß, dass es schon eine Menge Antworten gibt, aber ich musste den Anfang und das Ende der Saite intakt halten, aber auf die maximale Länge verkürzen.

    public static string TruncateMiddle(string source)
    {
        if (String.IsNullOrWhiteSpace(source) || source.Length < 260) 
            return source;

        return string.Format("{0}...{1}", 
            source.Substring(0, 235),
            source.Substring(source.Length - 20));
    }

Dies dient zum Erstellen von SharePoint-URLs mit einer maximalen Länge von 260 Zeichen. 

Die Länge eines Parameters wurde nicht konstant gemacht, da es eine Konstante 260 ist. Ich habe auch nicht die erste Teilzeichenlänge zu einem Parameter gemacht, weil ich möchte, dass er an einem bestimmten Punkt unterbrochen wird. Schließlich ist der zweite Teilstring die Länge der Quelle - 20, da ich die Ordnerstruktur kenne. 

Dies kann leicht an Ihre speziellen Bedürfnisse angepasst werden.

1
Paul Haan

Ich bevorzuge die Antwort von jpierson, aber in keinem der Beispiele, die ich hier sehen kann, wird ein ungültiger maxLength-Parameter verwendet, z. B. wenn maxLength <0 ist.

Sie haben die Wahl, entweder den Fehler in Try/Catch zu behandeln, den Parameter maxLength auf 0 zu klemmen, oder, wenn maxLength kleiner als 0 ist, eine leere Zeichenfolge zurückzugeben.

Nicht optimierter Code:

public string Truncate(this string value, int maximumLength)
{
    if (string.IsNullOrEmpty(value) == true) { return value; }
    if (maximumLen < 0) { return String.Empty; }
    if (value.Length > maximumLength) { return value.Substring(0, maximumLength); }
    return value;
}
1
deegee

Hier ist eine vb.net-Lösung. Markieren Sie, dass die if-Anweisung (obwohl hässlich) die Leistung verbessert, da die Zeichenfolge-Anweisung nicht erforderlich ist, wenn string bereits kleiner als maxlength ....__ ist. Wenn Sie eine Erweiterung zu string machen, ist dies einfach benutzen...

 <System.Runtime.CompilerServices.Extension()> _
    Public Function Truncate(String__1 As String, maxlength As Integer) As String
        If Not String.IsNullOrEmpty(String__1) AndAlso String__1.Length > maxlength Then
            Return String__1.Substring(0, maxlength)
        Else
            Return String__1
        End If
    End Function
1
Jeroen Bom

Ich weiß, dass es hier schon eine Menge Antworten gibt, aber dies ist die, mit der ich gegangen bin. Sie behandelt sowohl Null-Strings als auch die Situation, in der die übergebene Länge negativ ist:

public static string Truncate(this string s, int length)
{
    return string.IsNullOrEmpty(s) || s.Length <= length ? s 
        : length <= 0 ? string.Empty 
        : s.Substring(0, length);
}
1
Ed B

TruncateString

public static string _TruncateString(string input, int charaterlimit)
{
    int characterLimit = charaterlimit;
    string output = input;

    // Check if the string is longer than the allowed amount
    // otherwise do nothing
    if (output.Length > characterLimit && characterLimit > 0)
    {
        // cut the string down to the maximum number of characters
        output = output.Substring(0, characterLimit);
        // Check if the character right after the truncate point was a space
        // if not, we are in the middle of a Word and need to remove the rest of it
        if (input.Substring(output.Length, 1) != " ")
        {
            int LastSpace = output.LastIndexOf(" ");

            // if we found a space then, cut back to that space
            if (LastSpace != -1)
            {
                output = output.Substring(0, LastSpace);
            }
        }
        // Finally, add the "..."
        output += "...";
    }
    return output;
}
0
Sud

Als Ergänzung zu den oben diskutierten Möglichkeiten möchte ich meine Lösung mit Ihnen teilen. Es ist eine Erweiterungsmethode, die null zulässt (gibt string.Empty zurück). Vorsicht, es ist nicht leistungsoptimiert.

public static string Truncate(this string value, int maxLength) =>
    (value ?? string.Empty).Substring(0, (value?.Length ?? 0) <= (maxLength < 0 ? 0 : maxLength) ? (value?.Length ?? 0) : (maxLength < 0 ? 0 : maxLength));
public static string Truncate(this string value, int maxLength, string Ellipsis) =>
    string.Concat(value.Truncate(maxLength - (((value?.Length ?? 0) > maxLength ? Ellipsis : null)?.Length ?? 0)), ((value?.Length ?? 0) > maxLength ? Ellipsis : null)).Truncate(maxLength);
0