Wie kann ich meine Zeichenfolgen mit einem "..." abschneiden, wenn sie zu lang sind?

84

Hoffe jemand hat eine gute Idee. Ich habe Zeichenfolgen wie diese:

abcdefg
abcde
abc

Was ich brauche, ist, dass sie so behandelt werden, dass sie mehr als eine bestimmte Länge zeigen:

abc ..
abc ..
abc

Gibt es einen einfachen C # -Code, den ich dafür verwenden kann?

Melonie
quelle
Wo willst du das machen? - in einer Forms- oder WPF-App oder einer Website - bitte geben Sie weitere Details an!
Barry Kaye
2
Das Problem bei den meisten Lösungen ist, dass sie eine Anzahl von Chars als Grenze verwenden. Leider kann die grafische Breite stark variieren. Und dann gibt es UTF-16-
Ersatzzeichen
12
Dies ist KEIN Duplikat der vorgeschlagenen Frage. Dies ist eine sehr allgemeine Frage, während das vorgeschlagene Duplikat eine äußerst spezifische Frage ist.
JasonMArcher
2
Dies ist absolut kein Duplikat der vorgeschlagenen Frage.
Seth
2
Diese Frage kommt dem vorgeschlagenen Duplikat nicht einmal nahe, bitte entfernen Sie das Duplikatattribut. Danke.
Daniel Leiszen

Antworten:

146

Hier ist die Logik, die in einer Erweiterungsmethode zusammengefasst ist:

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

Verwendung:

var s = "abcdefg";

Console.WriteLine(s.Truncate(3));
Bryan Watts
quelle
1
Vielen Dank, Bryan. Ihre Antwort sieht gut aus. Bitte entschuldigen Sie meine einfache Frage, aber wie verwende ich eine Erweiterungsmethode?
Melony
1
@ Melony: Bearbeitet, um die Verwendung einzuschließen.
Bryan Watts
11
… (Auslassungspunkte) ist das richtige Symbol für diejenigen, die sich darum kümmern. Unicode U + 2026.
Malako
3
schnelle Ergänzung, um eine
Nullprüfung einzuschließen
1
danke @Malako: value.Substring(0, maxChars) + (char)0x2026;
Pierre
8
public string TruncString(string myStr, int THRESHOLD)
{
    if (myStr.Length > THRESHOLD)
        return myStr.Substring(0, THRESHOLD) + "...";
    return myStr;
}

Ignorieren Sie die Namenskonvention, nur für den Fall, dass er die Variable THRESHOLD tatsächlich benötigt oder wenn sie immer dieselbe Größe hat.

Alternative

string res = (myStr.Length > THRESHOLD) ? myStr.Substring(0, THRESHOLD) + ".." : myStr;
Jesus Ramos
quelle
Ist es möglich, daraus etwas mit einer Zeile zu machen, das ich inline verwenden könnte?
Melony
2
Dies kann zu ungültigen Zeichenfolgen führen, wenn ein Codepunkt in der Mitte aufgeteilt wird :(
CodesInChaos
7

Alles sehr gute Antworten, aber um es ein wenig aufzuräumen, wenn Ihre Zeichenfolgen Sätze sind, brechen Sie Ihre Zeichenfolge nicht mitten in einem Wort.

private string TruncateForDisplay(this string value, int length)
{
  if (string.IsNullOrEmpty(value)) return string.Empty;
  var returnValue = value;
  if (value.Length > length)
  {
    var tmp = value.Substring(0, length) ;
    if (tmp.LastIndexOf(' ') > 0)
       returnValue = tmp.Substring(0, tmp.LastIndexOf(' ') ) + " ...";
  }                
  return returnValue;
}
JStevens
quelle
Dies ist die einzige Antwort, die keine Wörter aufbricht. Daher die einzig richtige IMO.
mxmissile
@mxmissile - Angesichts der OP-Daten für "abcdefg", abgeschnitten auf 3 Zeichen, geht zu "abc ...", selbst wenn dies funktionieren würde, wäre es überhaupt nicht korrekt. Die OP-Beispieldaten zeigen deutlich ein hartes Abschneiden in der Mitte des zusammenhängenden Textes. Schlimmer noch, diese Antwort würde einen Fehler erzeugen. Da die Daten kein Leerzeichen enthalten, LastIndexOfwürde der Wert -1 zurückgeben und Substringeinen Laufzeitfehler verursachen.
4

Hier ist eine Version, die die Länge der Ellipsen berücksichtigt:

    public static string Truncate(this string value, int maxChars)
    {
        const string ellipses = "...";
        return value.Length <= maxChars ? value : value.Substring(0, maxChars - ellipses.Length) + ellipses;
    }
Jon
quelle
4
Wenn Sie das Auslassungszeichen verwenden, ist dies nicht erforderlich. Die Länge des Charakters wird immer 1 seinconst char ellipse = (char)0x2026;
Pierre
3

In .NET Framework gibt es keine integrierte Methode, die dies ausführt. Dies ist jedoch eine sehr einfache Methode, um sich selbst zu schreiben. Hier sind die Schritte, versuchen Sie es selbst und lassen Sie uns wissen, was Sie sich einfallen lassen.

  1. Erstellen Sie eine Methode, möglicherweise eine Erweiterungsmethode public static void TruncateWithEllipsis(this string value, int maxLength)

  2. Überprüfen Sie maxLengthanhand der LengthEigenschaft, ob der übergebene Wert größer als der angegebene Wert ist . Wenn das valuenicht größer als ist maxLength, geben Sie einfach das zurück value.

  3. Wenn wir den übergebenen Wert nicht unverändert zurückgegeben haben, wissen wir, dass wir ihn abschneiden müssen. Wir müssen also mit der SubStringMethode einen kleineren Abschnitt des Strings erhalten . Diese Methode gibt einen kleineren Abschnitt einer Zeichenfolge basierend auf einem angegebenen Start- und Endwert zurück. Die Endposition wurde vom maxLengthParameter übergeben. Verwenden Sie diese.

  4. Geben Sie den Unterabschnitt der Zeichenfolge plus die Auslassungspunkte zurück.

Eine gute Übung für später wäre es, die Methode zu aktualisieren und sie erst nach vollständigen Worten zu unterbrechen. Sie können auch eine Überladung erstellen, um anzugeben, wie eine Zeichenfolge abgeschnitten werden soll. Beispielsweise könnte die Methode "(für mehr klicken)" anstelle von "..." zurückgeben, wenn Ihre Anwendung so eingerichtet ist, dass durch Klicken mehr Details angezeigt werden.

Bob
quelle
2

Code dahinter:

string shorten(sting s)
{
    //string s = abcdefg;
    int tooLongInt = 3;

    if (s.Length > tooLongInt)
        return s.Substring(0, tooLongInt) + "..";

    return s;
}

Markup:

<td><%= shorten(YOUR_STRING_HERE) %></td>
VMAtm
quelle
Wie könnte ich das einfügen in: "<td>" + string + "<\ td>"?
Melony
2

Vielleicht ist es besser, eine Methode für diesen Zweck zu implementieren:

string shorten(sting yourStr)
{
//Suppose you have a string yourStr, toView and a constant value 

    string toView;
    const int maxView = 3;

    if (yourStr.Length > maxView)
        toView = yourStr.Substring(0, maxView) + " ..."; // all you have is to use Substring(int, int) .net method
    else
        toView = yourStr;
return toView;
}

quelle
1
string s = "abcdefg";
if (s.length > 3)
{
    s = s.substring(0,3);
}

Sie können die Teilzeichenfolgenfunktion verwenden.

Jethro
quelle
1

Ich habe diese Frage gefunden, nachdem ich nach "C # Auslassungspunkte" gesucht habe. Mit verschiedenen Antworten habe ich meine eigene Lösung mit den folgenden Funktionen erstellt:

  1. Eine Erweiterungsmethode
  2. Fügen Sie eine Ellipse hinzu
  3. Machen Sie die Auslassungspunkte optional
  4. Stellen Sie sicher, dass die Zeichenfolge nicht null oder leer ist, bevor Sie versuchen, sie abzuschneiden.

    public static class StringExtensions
    {
        public static string Truncate(this string value, 
            int maxLength, 
            bool addEllipsis = false)
        {
            // Check for valid string before attempting to truncate
            if (string.IsNullOrEmpty(value)) return value;
    
            // Proceed with truncating
            var result = string.Empty;
            if (value.Length > maxLength)
            {
                result = value.Substring(0, maxLength);
                if (addEllipsis) result += "...";
            }
            else
            {
                result = value;
            }
    
            return result;
        }
    }
    

Ich hoffe das hilft jemand anderem.

Tod Birdsall
quelle
0

Klar, hier ist ein Beispielcode:

string str = "abcdefg";
if (str.Length > X){
   str = str.Substring(0, X) + "...";
}
Justin Ethier
quelle
0

Ich habe dieses Problem vor kurzem. Ich habe eine "Status" -Nachricht in einem nvarcharMAX DB-Feld mit 4000 Zeichen gespeichert. Meine Statusmeldungen bauten sich jedoch auf und trafen die Ausnahme.

Aber es war kein einfacher Fall des Abschneidens, da ein beliebiges Abschneiden einen Teil einer Statusmeldung verwaisen würde, also musste ich wirklich an einem konsistenten Teil der Zeichenfolge "abschneiden".

Ich habe das Problem gelöst, indem ich den String in ein String-Array konvertiert, das erste Element entfernt und dann in einen String wiederhergestellt habe. Hier ist der Code ("CurrentStatus" ist die Zeichenfolge, die die Daten enthält) ...

        if (CurrentStatus.Length >= 3750)
        {
            // perform some truncation to free up some space.

            // Lets get the status messages into an array for processing...
            // We use the period as the delimiter, then skip the first item and re-insert into an array.

            string[] statusArray = CurrentStatus.Split(new string[] { "." }, StringSplitOptions.None)
                                    .Skip(1).ToArray();

            // Next we return the data to a string and replace any escaped returns with proper one.
            CurrentStatus = (string.Join(".", statusArray))
                                    .Replace("\\r\\n", Environment.NewLine);


        }

Hoffe es hilft jemandem aus.

Darren Street
quelle