Wie schneide ich eine .NET-Zeichenfolge ab?

406

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 den Einschränkungen 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 im maxLengthAllgemeinen die Grenzen der Zeichenfolge überschritten werden value. Natürlich könnte ich eine Funktion wie die folgende schreiben, aber ich hatte gehofft, dass so etwas bereits 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?

Steve Guidi
quelle
24
Für den Datensatz sind Zeichenfolgen unveränderlich. Sie können sie nicht abschneiden. Sie können nur eine abgeschnittene Kopie davon zurückgeben. Nitpicky, ich weiß.
John Weldon
2
@ John Weldon: Das ist wahrscheinlich der Grund, warum die Member-Funktion nicht existiert - sie folgt nicht der Semantik des Datentyps. StringBuilderNebenbei bemerkt, können Sie durch Verkürzen der Länge abschneiden, müssen jedoch die Längenprüfung durchführen, um eine Verbreiterung der Zeichenfolge zu vermeiden.
Steve Guidi
1
Unabhängig davon, welche Lösung Sie auswählen, müssen Sie eine Prüfung für eine Nullzeichenfolge hinzufügen, bevor Sie Substring aufrufen oder auf die Length-Eigenschaft zugreifen.
Ray
3
@SteveGuidi - Wenn das der Fall wäre, gäbe es keine Funktionen wie Trimmen oder Ersetzen, die mit ähnlichen semantischen Problemen konfrontiert sind
Chris Rogers
1
@JohnWeldon Zufälliger als Microsoft selbst sind sie zufällig - sie dokumentieren beispielsweise gerne so, .Trim()dass es irreführend klingt, als würde es die Zeichenfolge mutieren
Mark Amery

Antworten:

620

Truncate()Leider gibt es keine Methode für Zeichenfolgen. Sie müssen diese Art von Logik selbst schreiben. Sie können dies jedoch in eine Erweiterungsmethode einbinden, damit Sie sie nicht überall duplizieren 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);
LBushkin
quelle
5
Tolle Lösung, aber daran erinnert, dass dies nur in NET 3.5 und höher funktioniert. Versuchen Sie es nicht in NET2.0.
Jedi Master Spooky
7
Solange Sie sich in VS 2008 und vermutlich in VS 2010 befinden, können Sie dies auch dann tun, wenn Sie auf .Net 2.0 abzielen. danielmoth.com/Blog/…
Mark
4
Dies schlägt fehl, wenn maxLengthein negativer Wert vorliegt.
Bernard
42
@Bernard, dies soll fehlschlagen, wenn maxLength negativ ist. Jedes andere Verhalten wäre unerwartet.
Bojingo
12
Sie können Erweiterungsmethoden für Nullwerte aufrufen.
Joel Malone
127

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));
    }
}
CaffGeek
quelle
10
Klug! Der folgende Ausdruck ist optimiert, um einen Verweis auf die ursprüngliche Zeichenfolge zurückzugeben : value.Substring(0, value.Length).
Steve Guidi
4
Leider ist es nicht für Fälle optimiert, in denen value.Length kleiner als MaxLength ist, was in einigen Daten häufig vorkommt. Außerdem sollte die Length-Eigenschaft für Zeichenfolgen großgeschrieben werden.
Jpierson
1
Dies schlägt fehl, wenn maxLengthein negativer Wert vorliegt.
Bernard
7
@Bernard, so wird eine Menge Dinge , die im Rahmen ... aber wenn ich es überprüfen ... ich entweder auf Standard haben maxLengthzu 0oder value.Length; oder ich muss ein ArgumentOutOfRangeException... werfen , was in diesem Fall sinnvoller ist und Substringsowieso schon geworfen wird .
CaffGeek
2
Ein bisschen kürzer:return string.IsNullOrEmpty(value) ? value : value.Substring(0, Math.Min(value.Length, maxLength));
user1127860
43

Ich dachte, ich würde meine Implementierung einwerfen, da ich glaube, dass sie alle Fälle abdeckt, die von den anderen angesprochen wurden, und dies auf eine prägnante Art und Weise, die immer noch lesbar ist.

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 eröffnet die Methode zur Verwendung als Erweiterungsmethode, indem das Schlüsselwort this verwendet wird, genau wie es LBushkin in seiner Lösung tut .

jpierson
quelle
Dies schlägt fehl, wenn maxLengthein negativer Wert vorliegt.
Bernard
15
@Bernard - Ich würde empfehlen, keinen negativen Wert für das Argument maxLength zu übergeben, da es sich um einen unerwarteten Wert handelt. Die Teilstring-Methode verfolgt denselben Ansatz, sodass es keinen Grund gibt, die ausgelöste Ausnahme zu verbessern.
Jpierson
Ich denke nicht, dass der IsNullOrEmpty-Check notwendig ist? (1) Wenn der Wert null ist, sollte es keine Möglichkeit geben, diese Erweiterungsmethode darauf aufzurufen. (2) Wenn value die leere Zeichenfolge ist, schlägt die Prüfung value.Length> maxLength fehl.
Jon Schneider
8
@ JonSchneider, IsNullOrEmpty ist erforderlich, da dies eine Erweiterungsmethode ist. Wenn Sie eine Variable vom Typ string haben, der eine Null zugewiesen wurde, fügt der Compiler vor dem Aufrufen dieser Methode keine Nullprüfung ein. Technisch gesehen ist dies immer noch eine statische Methode der statischen Klasse. Also: stringVar.Truncate (2) Kompiliert als: StringExt.Truncate (stringVar, 2);
Jeff B
40

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 truncateMethode war "deutlich" schneller. # Mikrooptimierung

Früh

  • abgeschnitten 10 5788 abgelaufene Ticks (0,5788 ms) [in 10K-Wiederholungen 5,788E-05 ms pro]
  • smart-trunc10 8206 verstrichene Ticks (0,8206 ms) [in 10K-Wiederholungen 8,206E-05 ms pro]
  • stringbuilder10 10557 verstrichene Ticks (1,0557 ms) [in 10K-Wiederholungen 0,00010557 ms pro]
  • concat10 45495 verstrichene Ticks (4,5495 ms) [in 10K-Wiederholungen 0,00045495 ms pro]
  • newstring10 72535 verstrichene Ticks (7,2535 ms) [in 10K-Wiederholungen 0,00072535 ms pro]

Spät

  • verkürzte 44 8835 Ticks verstrichen (0,8835 ms) [in 10K-Wiederholungen 8,835E-05 ms pro]
  • stringbuilder44 13106 verstrichene Ticks (1,3106 ms) [in 10K-Wiederholungen 0,00013106 ms pro]
  • smart-trunc44 14821 verstrichene Ticks (1,4821 ms) [in 10K-Wiederholungen 0,00014821 ms pro]
  • newstring44 144324 verstrichene Ticks (14,4324 ms) [in 10K-Wiederholungen 0,00144324 ms pro]
  • concat44 174610 verstrichene Ticks (17,461 ms) [in 10K-Wiederholungen 0,0017461 ms pro]

Zu lang

  • verstrichene smart-trunc64 6944-Ticks (0,6944 ms) [in 10K-Wiederholungen 6,944E-05 ms pro]
  • truncate64 7686 verstrichene Ticks (0,7686 ms) [in 10K-Wiederholungen, 7,686E-05 ms pro]
  • stringbuilder64 13314 verstrichene Ticks (1,3314 ms) [in 10K-Wiederholungen 0,00013314 ms pro]
  • newstring64 177481 abgelaufene Ticks (17,7481 ms) [in 10K-Wiederholungen 0,00177481 ms pro]
  • concat64 241601 Ticks verstrichen (24,1601 ms) [in 10K Wiederholungen 0,00241601 ms pro]
drzaus
quelle
Vielen Dank für alle nützlichen Benchmarks! ... und Linkpad rockt!
Sunsetquest
Es war mir egal, dass Linqpad diese Dinge tun konnte
Jefissu
38

In .NET 4.0 können Sie folgende TakeMethode verwenden:

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

Nicht auf Effizienz getestet!

Dylan Nicholson
quelle
27

Sie können LINQ verwenden ... Sie müssen die Zeichenfolgenlänge nicht mehr überprüfen. Zugegeben, vielleicht nicht die effizienteste, aber es macht Spaß.

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

oder

string result = new string(value.Take(maxLength).ToArray());
zähmt
quelle
2
Warum ist dies nicht die akzeptierte Antwort? Was ist am einfachsten, schreiben Sie Ihre eigene Erweiterungsmethode, die Sie pflegen / dokumentieren müssen, oder verwenden Sie etwas EINGEBAUTES wie .Take
Don Cheadle
9
@mmcrae Linq ist vielleicht einfacher, aber es ist auch viel langsamer. Mein Benchmark sagt ~ 400 ms für Linq und nur ~ 24 ms für Teilzeichenfolge für 1 Million Iterationen.
Hein Andre Grønnestad
Diese Lösung sollte niemals verwendet werden. Wie in zwei obigen Kommentaren erwähnt, gibt es immer eine Speicherzuweisung, selbst wenn die vorhandene Zeichenfolge nicht größer als die maximale Länge ist. Es ist auch sehr langsam.
Kamarey
15

Ich habe meine in einer Zeile so gemacht

value = value.Length > 1000 ? value.Substring(0, 1000) : value;
SeanMC
quelle
2
-1; Dies fügt überhaupt nichts hinzu, was nicht bereits in der akzeptierten Antwort enthalten war.
Mark Amery
2
@markamery ist eine kürzere Alternative mit weniger Code zum Schreiben und Aktualisieren, wenn Sie ihn verwenden müssen. Magst du es nicht? Verwenden Sie es nicht
SeanMC
Schnell, einfach und schnell. Das brauchte ich. Vielen Dank!
Peter
14

Es scheint, dass noch niemand dies gepostet hat:

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

Die Verwendung des Operators && macht es geringfügig besser als die akzeptierte Antwort.

Darren
quelle
13

Das .NET Framework verfügt über eine API zum Abschneiden einer Zeichenfolge wie folgt:

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

Aber in einer C # -App werden Sie wahrscheinlich lieber Ihre eigene rollen als eine Abhängigkeit von Microsoft.VisualBasic.dll, dessen Hauptziel die Abwärtskompatibilität ist.

Joe
quelle
"Das .NET Framework hat eine API" widersprechen Sie sich. Das ist eine VB.NET API
Camilo Terevinto
9
@CamiloTerevinto - Es handelt sich um eine API, die im Lieferumfang von .NET Framework enthalten ist und aus jeder verwalteten Sprache aufgerufen werden kann.
Joe
1
Die VB DLL enthält viele gute Sachen. Warum sind so viele Entwickler dagegen?
Michael Z.
Leider keine .NET Core-Unterstützung. In der Tat sind die gesamten Microsoft.VisualBasic.StringsModule in .NET Core ziemlich leer .
Mark Amery
1
Obwohl ich dem Kommentar von Joe zustimme, fühle ich mich immer noch nicht richtig, etwas Spezielles für VB aus anderen Sprachen zu nennen. Wenn es in "VB DLL" so viele gute Sachen gibt, warum nicht an einem gemeinsamen Ort? Wer weiß, was Microsoft morgen mit diesen Dingen machen wird? Stoppen Sie die Unterstützung oder so ..
Kamarey
12

Eine andere Lösung:

return input.Substring(0, Math.Min(input.Length, maxLength));
Marek Malczewski
quelle
6

Ich weiß, dass dies eine alte Frage ist, 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ückgabe: Hallo ...

kein Logo
quelle
@SarjanWebDev Dieses Sonderzeichen wird als "." in cmd.exe
Neal Ehardt
5

Eine ähnliche Variante mit dem Null-Propagationsoperator 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 hier im Wesentlichen valuezweimal prüfen, ob null ist.

Jamie Rees
quelle
5

Noch keine Methode zum Abschneiden im Jahr 2016 für C # -Strings. 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"
Tobias Schiele
quelle
4

Nehmen Sie @CaffGeek und vereinfachen Sie es:

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

Beachten Sie, dass das Abschneiden einer Zeichenfolge nicht nur das Schneiden einer Zeichenfolge in einer bestimmten Länge bedeutet, sondern auch darauf achten muss, das Wort nicht zu teilen.

zB Zeichenfolge: Dies ist eine Testzeichenfolge.

Ich möchte es um 11 schneiden. 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 benutze, ist vielleicht auch nicht so perfekt, aber sie kann den größten Teil der Situation 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());
} 
Sen K. Mathew
quelle
4

Warum nicht:

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

dh im Ereignisfeld value.Length < maxLengthLeerzeichen bis zum Ende oder den Überschuss abschneiden.

Sri
quelle
Sie generieren doppelt so viele Zeichenfolgenobjekte und es könnte eine NullReferenceException aus dem PadRight-Aufruf auslösen, wenn der Wert null ist, was unangemessen ist. Es sollte eine ArgumentNullException sein.
Jeremy
1
@Jeremy Ich verstehe nicht "es könnte eine NullReferenceException aus dem PadRight-Aufruf auslösen, wenn der Wert null ist"; habe ich nicht erwähnt "// check string.IsNullOrEmpty (value) und handle danach."
Sri
3

Nur für den Fall, dass es hier 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,"~")
KR
quelle
2

Aus Gründen der (Über-) Komplexität werde ich meine überladene Version hinzufügen, die die letzten 3 Zeichen durch ein Auslassungszeichen 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)); 
}
SoftDev
quelle
2

Meine zwei Cent mit Beispiellänge von 30:

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

Ich bevorzuge die Antwort von jpierson, aber keines der hier gezeigten Beispiele behandelt einen ungültigen maxLength-Parameter, z. B. wenn maxLength <0 ist.

Sie können entweder den Fehler in einem Versuch / Fang behandeln, den Parameter maxLength min auf 0 klemmen oder, wenn maxLength kleiner als 0 ist, eine leere Zeichenfolge zurückgeben.

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;
}
deegee
quelle
3
Beachten Sie, dass ich mich in meiner Implementierung dafür entschieden habe, den Fall nicht zu behandeln, in dem die maximale Länge kleiner als 0 ist, da ich dachte, ich würde nur eine ArgumentOutOfRangeExcpetion auslösen, die im Wesentlichen das tut, was string.Substring () für mich tut.
Jpierson
1

Hier ist eine vb.net-Lösung. Markieren Sie, dass die if-Anweisung (obwohl hässlich) die Leistung verbessert, da wir die Teilzeichenfolgenanweisung nicht benötigen, wenn der String bereits kleiner als die maximale Länge ist. Indem Sie ihn zu einer Erweiterung des Strings machen, ist er einfach zu verwenden. ..

 <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
Jeroen Bom
quelle
In VB.net können Sie "Not String.IsNullOrEmpty (String__1)" durch "String__1 <> Nothing" ersetzen. Es ist etwas kürzer. Der Standardwert für Zeichenfolgen ist eine leere Zeichenfolge. Mit "<> Nothing" werden sowohl null als auch leere Zeichenfolgen überprüft. Testen Sie es mit: Truncate ("", 50) und Truncate (Nothing, 50)
jrjensen
In VB können Sie Links (Zeichenfolge, maximale Länge)
Michael Z.
1

Ich weiß, dass es bereits eine Menge Antworten gibt, aber ich musste den Anfang und das Ende der Zeichenfolge intakt halten, sie aber auf unter die maximale Länge kü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.

Ich habe die Länge nicht zu einem Parameter gemacht, da es sich um eine Konstante 260 handelt. Ich habe auch die erste Teilzeichenfolgenlänge nicht zu einem Parameter gemacht, weil ich möchte, dass sie an einem bestimmten Punkt unterbrochen wird. Schließlich ist der zweite Teilstring die Länge der Quelle - 20, da ich die Ordnerstruktur kenne.

Dies könnte leicht an Ihre spezifischen Bedürfnisse angepasst werden.

Paul Haan
quelle
1

Ich weiß, dass es hier bereits eine Menge Antworten gibt, aber dies ist die, mit der ich gegangen bin, die sowohl Nullzeichenfolgen als auch die Situation behandelt, 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);
}
Ed B.
quelle
1

In C # 8 kann die neue Funktion "Bereiche" verwendet werden ...

value = value[..Math.Min(30, value.Length)];
Sunsetquest
quelle
0

Es gibt nichts in .net dafür, was mir bekannt ist - hier ist meine Version, die "..." hinzufügt:

public static string truncateString(string originalString, int length) {
  if (string.IsNullOrEmpty(originalString)) {
   return originalString;
  }
  if (originalString.Length > length) {
   return originalString.Substring(0, length) + "...";
  }
  else {
   return originalString;
  }
}
Strahl
quelle
2
Ihre Version enthält Zeichenfolgen, die 3 Zeichen länger als die angeforderte Länge sind, falls sie abgeschnitten werden. Außerdem sind die dreifachen Punkte in der Darstellung wirklich nur von Bedeutung. Ich würde sie nicht in einer Datenbank wie der speichern, die der vom OP angegebene Anwendungsfall ist.
MarioDS
0

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;
}
Sud
quelle
2
Warum wird Ihrem öffentlichen Methodennamen ein Unterstrich vorangestellt?
Michael Z.
0

Als Ergänzung zu den oben diskutierten Möglichkeiten möchte ich meine Lösung teilen. Es ist eine Erweiterungsmethode, die null zulässt (gibt string.Empty zurück), außerdem gibt es eine zweite .Truncate () für die Verwendung mit Auslassungspunkten. Achtung, 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);
Raymond Osterbrink
quelle
-1
public static string Truncate( this string value, int maxLength )
    {
        if (string.IsNullOrEmpty(value)) { return value; }

        return new string(value.Take(maxLength).ToArray());// use LINQ and be happy
    }
TapiocaCom
quelle
Der ToArray()Anruf hier ist nur unnötiger Aufwand; Mit zB können String.ConcatSie eine Zeichenfolge aus einer Aufzählung von Zeichen erstellen, ohne über ein Array gehen zu müssen.
Mark Amery
-3

Zeichenfolge abschneiden

public static string TruncateText(string strText, int intLength)
{
    if (!(string.IsNullOrEmpty(strText)))
    {                                
        // split the text.
        var words = strText.Split(' ');

        // calculate the number of words
        // based on the provided characters length 
        // use an average of 7.6 chars per word.
        int wordLength = Convert.ToInt32(Math.Ceiling(intLength / 7.6));

        // if the text is shorter than the length,
        // display the text without changing it.
        if (words.Length <= wordLength)
            return strText.Trim();                

        // put together a shorter text
        // based on the number of words
        return string.Join(" ", words.Take(wordLength)) + " ...".Trim();
    }
        else
        {
            return "";
        }            
    }
VT
quelle
Dies beantwortet nicht die Frage des OP. Erstens sollte es eine Mitgliedsfunktion sein (obwohl Sie sie als Erweiterungsmethode geschrieben haben). Zweitens legt das OP nicht fest, dass der Text geteilt und die Wörter auf ca. 7,6 Zeichen pro Wort.
Wicher Visser
7.6 ist nur eine Zahl. Sie können jede andere Nummer schreiben, die Sie wünschen. Dies war zufällig eine durchschnittliche englische Wortlänge. Ich habe es bei Google gefunden. Die Verwendung von split ist nur eine einfache Möglichkeit, die Wörter nach Leerzeichen aufzuteilen. Ich glaube nicht, dass Sie ein halbes Wort anzeigen wollen! Wenn Sie also keine Schleife durchlaufen, um einen leeren Bereich zu finden, für den mehr Code erforderlich ist, können Sie auf einfache Weise eine Zeichenfolge abschneiden und vollständige Wörter anzeigen. Dadurch wird sichergestellt, dass eine Zeichenfolge nicht länger als die angegebene Länge ist und Sie keine fehlerhaften Wörter haben.
VT
-4

Dies ist der Code, den ich normalerweise verwende:

string getSubString(string value, int index, int length)
        {
            if (string.IsNullOrEmpty(value) || value.Length <= length)
            {
                return value;
            }
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            for (int i = index; i < length; i++)
            {
                sb.AppendLine(value[i].ToString());
            }
            return sb.ToString();
        }
user3390116
quelle
5
Bitte beachten Sie, dass das Verketten von Zeichenfolgen mit + = eine teure Operation ist, insbesondere beim erneuten Erstellen von Zeichen für Zeichen. .NET-Zeichenfolgen sind unveränderlich. In diesem Fall wird jedes Mal in Ihrer Schleife eine neue Zeichenfolge erstellt.
Steve Guidi
@SteveGuidi-Strings sind nicht unveränderlich, sie maskieren sich nur als unveränderlich. Ich wünschte, Strings wären echte unveränderliche Primitive, also könnte ich String und String haben?, Aber leider sind sie keine Primitiven.
Chris Marisic
Sie sagen, teuer, als ob die Leistungskosten erheblich wären. Ich habe es geändert, um stringBuilder zu verwenden, aber ich finde, dass mit + = leichter zu erkennen ist, was los ist. Ich wollte nur, dass das OP den Code leicht versteht.
user3390116