Jak mogę skrócić ciągi za pomocą „…”, jeśli są za długie?


84

Mam nadzieję, że ktoś ma dobry pomysł. Mam takie struny:

abcdefg
abcde
abc

To, czego potrzebuję, to ich wycięcie, aby pokazać w ten sposób, jeśli długość jest większa niż określona:

abc ..
abc ..
abc

Czy jest jakiś prosty kod C #, którego mogę użyć do tego?


Gdzie chcesz to zrobić? - w aplikacji Forms, WPF lub na stronie internetowej - podaj więcej szczegółów!
Barry Kaye

2
Problem z większością rozwiązań polega na tym, że Charjako limit używają liczby s. Niestety szerokość grafiki może się znacznie różnić. A potem są surogaty UTF-16, łączące znaki, ...
CodesInChaos

12
To NIE jest duplikatem sugerowanego pytania. Jest to bardzo ogólne pytanie, podczas gdy sugerowany duplikat jest bardzo szczegółowym pytaniem.
JasonMArcher

2
To absolutnie nie jest powtórzeniem sugerowanego pytania.
Seth

2
To pytanie nie jest nawet zbliżone do sugerowanego duplikatu, usuń zduplikowany atrybut. Dzięki.
Daniel Leiszen

Odpowiedzi:


148

Oto logika zawarta w metodzie rozszerzenia:

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

Stosowanie:

var s = "abcdefg";

Console.WriteLine(s.Truncate(3));

1
Dziękuję Bryan. Twoja odpowiedź wygląda dobrze. Proszę wybaczyć moje proste pytanie, ale jak użyć metody rozszerzenia?
Melony,

1
@Melony: edytowane w celu uwzględnienia użycia.
Bryan Watts,

11
… (Wielokropek) to właściwy symbol dla tych, którym zależy. Unicode U + 2026.
Malako

3
szybki dodatek zawierający czek null
james

1
dzięki @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;
}

Zignoruj ​​konwencję nazewnictwa, na wypadek gdyby faktycznie potrzebował zmiennej THRESHOLD lub jeśli ma ona zawsze ten sam rozmiar.

Alternatywnie

string res = (myStr.Length > THRESHOLD) ? myStr.Substring(0, THRESHOLD) + ".." : myStr;

Czy można zrobić z tego coś za pomocą jednej linii, której mógłbym użyć w tekście?
Melony,

2
To może produkować nieprawidłowe ciągi jeśli dzieli kodowy w środkowej :(
CodesInChaos

8

Wszystkie bardzo dobre odpowiedzi, ale żeby trochę uporządkować, jeśli twoje ciągi znaków są zdaniami, nie przerywaj łańcucha w środku słowa.

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

To jedyna odpowiedź, która nie rozbija słów. Dlatego jedyny poprawny IMO.
mxmissile

@mxmissile - biorąc pod uwagę dane OP, dla „abcdefg”, skróć do 3 znaków, przechodzi do „abc…”, nawet gdyby to zadziałało, nie byłoby to wcale poprawne. Przykładowe dane OP wyraźnie wskazują na twarde obcięcie w środku ciągłego tekstu. Co gorsza, taka odpowiedź spowodowałaby błąd. Ponieważ dane nie zawierają spacji, LastIndexOfzwróciłoby -1, a Substringspowodowałoby błąd w czasie wykonywania.

4

Oto wersja uwzględniająca długość elips:

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

4
jeśli używasz znaku wielokropka, nie ma takiej potrzeby. Długość postaci zawsze będzie wynosić 1const char ellipse = (char)0x2026;
Pierre

3

NET Framework nie ma wbudowanej metody, która to robi, jednak jest to bardzo łatwa metoda samodzielnego pisania. Oto kroki, spróbuj zrobić to sam i daj nam znać, co wymyśliłeś.

  1. Utwórz metodę, być może metodę rozszerzającą public static void TruncateWithEllipsis(this string value, int maxLength)

  2. Sprawdź, czy przekazana wartość jest większa niż maxLengthokreślona przy użyciu Lengthwłaściwości . Jeśli valuenie większe niż maxLength, po prostu zwróć plik value.

  3. Jeśli nie zwróciliśmy przekazanej wartości w takiej postaci, w jakiej jest, wiemy, że musimy ją obciąć. Musimy więc za pomocą SubStringmetody pobrać mniejszy fragment ciągu . Ta metoda zwróci mniejszą sekcję ciągu na podstawie określonej wartości początkowej i końcowej. Pozycja końcowa jest tym, co zostało przekazane przez maxLengthparametr, więc użyj tego.

  4. Zwróć sekcję podrzędną ciągu wraz z wielokropkiem.

Świetnym ćwiczeniem na później byłoby zaktualizowanie metody i przerwanie jej dopiero po pełnych słowach. Możesz również utworzyć przeciążenie, aby określić, w jaki sposób chcesz pokazać, że ciąg został obcięty. Na przykład metoda może zwrócić „(kliknij, aby zobaczyć więcej)” zamiast „…”, jeśli aplikacja jest skonfigurowana tak, aby wyświetlać więcej szczegółów po kliknięciu.


2

Kod za:

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

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

    return s;
}

Narzut:

<td><%= shorten(YOUR_STRING_HERE) %></td>

Jak mogę to zmieścić w: „<td>” + string + „<\ td>”?
Melony,

2

Może lepiej zaimplementować w tym celu metodę:

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

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

Możesz użyć funkcji Substring.


1

Znalazłem to pytanie po wyszukaniu „C # obcinaj wielokropek”. Korzystając z różnych odpowiedzi, stworzyłem własne rozwiązanie o następujących cechach:

  1. Metoda rozszerzenia
  2. Dodaj wielokropek
  3. Ustaw wielokropek jako opcjonalny
  4. Sprawdź, czy ciąg nie jest zerowy ani pusty, zanim spróbujesz go obciąć.

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

Mam nadzieję, że to pomoże komuś innemu.


0

Jasne, oto przykładowy kod:

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

0

Ostatnio mam ten problem. Przechowywałem komunikat „status” w polu nvarcharMAX DB, które ma 4000 znaków. Jednak moje komunikaty o stanie narastały i trafiały w wyjątek.

Nie był to jednak prosty przypadek obcięcia, ponieważ dowolne obcięcie oznaczałoby oddzielenie części komunikatu o stanie, więc naprawdę musiałem „obciąć” spójną część ciągu.

Rozwiązałem problem, konwertując ciąg na tablicę ciągów, usuwając pierwszy element, a następnie przywracając go do ciągu. Oto kod („CurrentStatus” to ciąg przechowujący dane) ...

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


        }

Mam nadzieję, że to komuś pomoże.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.