2009-10-23 12 views
56

Ich versuche, einige lange Text in C# abzuschneiden, aber ich möchte nicht, dass meine Zeichenfolge durch ein Wort abgeschnitten wird. Hat jemand eine Funktion, mit der ich meine Zeichenfolge am Ende eines Wortes abschneiden kann?Kürzen Sie String auf ganze Wörter in .NET C#

Z. B:

"This was a long string..." 

Nicht:

"This was a long st..." 
+1

Könnten Sie Ihre aktuelle Lösung geben für Kürzen? – pyrocumulus

+2

@Cloud Just .Substring (0, ) – TimS

+2

Nun, wenn höher als die tatsächliche Zeichenfolge ist, löst der Teilstring eine Ausnahme aus, die eine zusätzliche Prüfung erfordert. –

Antwort

71

Vielen Dank für Ihre Antwort Dave. Ich habe die Funktion ein bisschen gezwickt und das ist, was ich verwende ... es sei denn, es noch mehr Kommentare sind;)

public static string TruncateAtWord(this string input, int length) 
{ 
    if (input == null || input.Length < length) 
     return input; 
    int iNextSpace = input.LastIndexOf(" ", length, StringComparison.Ordinal); 
    return string.Format("{0}...", input.Substring(0, (iNextSpace > 0) ? iNextSpace : length).Trim()); 
} 
+3

Außerdem rufe ich jetzt auch eine andere Zeichenfolgen-Dienstprogrammfunktion auf, die alle HTML-Tags ausblendet (mit RegEx). Dies minimiert das Risiko von fehlerhaftem HTML als Ergebnis der Kürzung, da alle Zeichenfolgen im Nur-Text-Format vorliegen. – TimS

+7

Beachten Sie, dass diese Methode nach dem ersten Leerzeichen * NACH dem angegebenen Längenwert sucht und fast immer bewirkt, dass die resultierende Zeichenfolge länger als der Wert ist. Um den letzten Platz vor der Länge zu finden, ersetzen Sie einfach 'input.LastIndexOf ("", length) 'bei der Berechnung von' iNextSpace'. – CBono

+3

+100 für CBonos Kommentar - das muss vorher sein! Für den Fall, dass ein langer Redeweg zu lange dauert, haben Sie eine lange Schlange, die weit über Ihre gewünschte Länge hinausgeht! – Jason

81

die folgenden Versuchen. Es ist ziemlich rudimentär. Findet nur den ersten Platz ab der gewünschten Länge.

public static string TruncateAtWord(this string value, int length) { 
    if (value == null || value.Length < length || value.IndexOf(" ", length) == -1) 
     return value; 

    return value.Substring(0, value.IndexOf(" ", length)); 
} 
+15

Perfekt! Und keine Regex in Sicht :) – TimS

+5

Es könnte sinnvoll sein, den ersten Platz VOR der gewünschten Länge zu finden? Ansonsten muss man raten, wie die gewünschte Länge ist? – mlsteeves

+1

Auch sollte -1 für nicht mit Regex;) – Goran

3

Wenn Sie Windows Forms verwenden, in der Graphics.DrawString Methode, gibt es eine Option in String angeben, wenn die Zeichenfolge abgeschnitten werden sollte, wenn sie nicht in den Bereich angegeben passt. Dadurch können Sie die Ellipsen nach Bedarf hinzufügen.

http://msdn.microsoft.com/en-us/library/system.drawing.stringtrimming.aspx

+0

Dies ist für eine ASP.Net-Seite, aber ich mache einige Win Forms Sachen so gut zu wissen! – TimS

2

nahm ich Ihren Ansatz ein wenig weiter:

public string TruncateAtWord(string value, int length) 
{ 
    if (value == null || value.Trim().Length <= length) 
     return value; 

    int index = value.Trim().LastIndexOf(" "); 

    while ((index + 3) > length) 
     index = value.Substring(0, index).Trim().LastIndexOf(" "); 

    if (index > 0) 
     return value.Substring(0, index) + "..."; 

    return value.Substring(0, length - 3) + "..."; 
} 

I benutze dies um Tweets zu kürzen.

5

Mein Beitrag:

public static string TruncateAtWord(string text, int maxCharacters, string trailingStringIfTextCut = "&hellip;") 
{ 
    if (text == null || (text = text.Trim()).Length <= maxCharacters) 
     return text; 

    int trailLength = trailingStringIfTextCut.StartsWith("&") ? 1 
                   : trailingStringIfTextCut.Length; 
    maxCharacters = maxCharacters - trailLength >= 0 ? maxCharacters - trailLength 
                : 0; 
    int pos = text.LastIndexOf(" ", maxCharacters); 
    if (pos >= 0) 
     return text.Substring(0, pos) + trailingStringIfTextCut; 

    return string.Empty; 
} 

Dies ist, was ich in meinen Projekten verwenden, optional mit Hinter. Der Text überschreitet niemals die Länge von maxCharacters + Trailing Text.

+0

+1 für die Verwendung von & hellip; :) – manudea

1

vereinfacht, hinzugefügt Trunking-Zeichen-Option und machte es zu einer Erweiterung.

public static string TruncateAtWord(this string value, int maxLength) 
    { 
     if (value == null || value.Trim().Length <= maxLength) 
      return value; 

     string ellipse = "..."; 
     char[] truncateChars = new char[] { ' ', ',' }; 
     int index = value.Trim().LastIndexOfAny(truncateChars); 

     while ((index + ellipse.Length) > maxLength) 
      index = value.Substring(0, index).Trim().LastIndexOfAny(truncateChars); 

     if (index > 0) 
      return value.Substring(0, index) + ellipse; 

     return value.Substring(0, maxLength - ellipse.Length) + ellipse; 
    } 
+0

das funktioniert einfach nicht wie vorgesehen. Bitte machen Sie zumindest einen Plausibilitätscheck, bevor Sie etwas hier veröffentlichen. – avs099

0

Ich benutze diese

public string Truncate(string content, int length) 
    { 
     try 
     { 
      return content.Substring(0,content.IndexOf(" ",length)) + "..."; 
     } 
     catch 
     { 
      return content; 
     } 
    } 
1

Heres, was ich kam mit. Dies ist, um den Rest des Satzes auch in Blöcken zu erhalten.

public static List<string> SplitTheSentenceAtWord(this string originalString, int length) 
    { 
     try 
     { 
      List<string> truncatedStrings = new List<string>(); 
      if (originalString == null || originalString.Trim().Length <= length) 
      { 
       truncatedStrings.Add(originalString); 
       return truncatedStrings; 
      } 
      int index = originalString.Trim().LastIndexOf(" "); 

      while ((index + 3) > length) 
       index = originalString.Substring(0, index).Trim().LastIndexOf(" "); 

      if (index > 0) 
      { 
       string retValue = originalString.Substring(0, index) + "..."; 
       truncatedStrings.Add(retValue); 

       string shortWord2 = originalString; 
       if (retValue.EndsWith("...")) 
       { 
        shortWord2 = retValue.Replace("...", ""); 
       } 
       shortWord2 = originalString.Substring(shortWord2.Length); 

       if (shortWord2.Length > length) //truncate it further 
       { 
        List<string> retValues = SplitTheSentenceAtWord(shortWord2.TrimStart(), length); 
        truncatedStrings.AddRange(retValues); 
       } 
       else 
       { 
        truncatedStrings.Add(shortWord2.TrimStart()); 
       } 
       return truncatedStrings; 
      } 
      var retVal_Last = originalString.Substring(0, length - 3); 
      truncatedStrings.Add(retVal_Last + "..."); 
      if (originalString.Length > length)//truncate it further 
      { 
       string shortWord3 = originalString; 
       if (originalString.EndsWith("...")) 
       { 
        shortWord3 = originalString.Replace("...", ""); 
       } 
       shortWord3 = originalString.Substring(retVal_Last.Length); 
       List<string> retValues = SplitTheSentenceAtWord(shortWord3.TrimStart(), length); 

       truncatedStrings.AddRange(retValues); 
      } 
      else 
      { 
       truncatedStrings.Add(retVal_Last + "..."); 
      } 
      return truncatedStrings; 
     } 
     catch 
     { 
      return new List<string> { originalString }; 
     } 
    } 
1

Auch diese Lösung arbeitet (nimmt die ersten 10 Wörter aus myString):

String.Join(" ", myString.Split(' ').Take(10))