2009-10-23 15 views
56

Sto cercando di troncare un lungo testo in C#, ma non voglio che la mia stringa venga troncata in parte da una parola. Qualcuno ha una funzione che posso usare per troncare la mia stringa alla fine di una parola?Stringa troncata su intere parole in .NET C#

es:

"This was a long string..." 
Non

:

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

Potrebbe dare la vostra attuale soluzione per troncare? – pyrocumulus

+2

@Cloud Just .Substring (0, ) – TimS

+2

Bene se è superiore alla stringa effettiva, la sottostringa genererà un'eccezione, richiedendo un controllo supplementare. –

risposta

71

Grazie per la risposta Dave. Ho ottimizzato la funzione un po 'e questo è quello che sto usando ... a meno che non ci sono altri commenti;)

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

Inoltre, ora sto chiamando un'altra funzione di utilità per le stringhe all'interno di questa, che rimuove qualsiasi tag HTML (usando RegEx). Questo riduce al minimo il rischio di errori di HTML come risultato del troncamento, poiché tutta la stringa sarà in testo normale. – TimS

+7

Si noti che questo metodo cerca il primo spazio * DOPO * il valore della lunghezza specificato, causando quasi sempre la stringa risultante più lunga del valore. Per trovare l'ultimo spazio prima della lunghezza, è sufficiente sostituire 'input.LastIndexOf (" ", length)' durante il calcolo di 'iNextSpace'. – CBono

+3

+100 per il commento di CBono - questo deve essere prima! Nell'eventualità di una lunga parola, il significato di questa corda è molto lungo e persistente per tutta la lunghezza desiderata! – Jason

81

provare quanto segue. È piuttosto rudimentale. Trova il primo spazio a partire dalla lunghezza desiderata.

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

Perfetto! E non una regex in vista :) – TimS

+5

Potrebbe avere senso trovare il primo spazio PRIMA della lunghezza desiderata? Altrimenti, devi indovinare qual è la lunghezza desiderata? – mlsteeves

+1

Anche dovrebbe essere -1 per non usare regex;) – Goran

3

Se si utilizza Windows forme, nel metodo Graphics.DrawString, c'è un'opzione in StringFormat per specificare se la stringa deve essere troncata, se non si adatta nella zona specificata. Questo gestirà l'aggiunta dei puntini di sospensione, se necessario.

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

+0

Questo è per una pagina ASP.Net, ma faccio alcune cose di Win Forms così buone da sapere! – TimS

2

Ho preso il vostro approccio un po' più avanti:

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 sto usando questo per troncare i tweet.

5

mio contributo:

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; 
} 

Questo è quello che uso nei miei progetti, con finale opzionale. Il testo non supererà mai i caratteri massimi + la lunghezza del testo finale.

+0

+1 per l'uso di & hellip; :) – manudea

1

semplificato, ha aggiunto l'opzione del carattere di trunking e ne ha reso un'estensione.

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

semplicemente non funziona come previsto. Si prega almeno di fare un controllo di sanità mentale prima di pubblicare qualsiasi cosa qui. – avs099

0

Io uso questo

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

Heres quello che mi è venuta. Questo è per ottenere il resto della frase anche in blocchi.

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

Questa soluzione funziona anche (prende prime 10 parole da myString):

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