Как я могу обрезать свои строки с помощью «…», если они слишком длинные?

84

Надеюсь, у кого-то есть хорошая идея. У меня есть такие строки:

abcdefg
abcde
abc

Мне нужно, чтобы они были показаны таким образом, если длина больше указанной:

abc ..
abc ..
abc

Есть ли какой-нибудь простой код на C #, который я могу использовать для этого?

Мелони
источник
Где ты хочешь это сделать? - в приложении Forms или WPF или на веб-сайте - пожалуйста, предоставьте более подробную информацию!
Barry Kaye
2
Проблема с большинством решений заключается в том, что они используют количество Chars в качестве ограничения. К сожалению, графическая ширина может сильно различаться. А еще есть суррогаты UTF-16, объединяющие символы, ...
CodesInChaos
12
Это НЕ дубликат предложенного вопроса. Это очень общий вопрос, в то время как предлагаемый дубликат - чрезвычайно конкретный вопрос.
JasonMArcher
2
Это абсолютно не повторение предложенного вопроса.
Сет,
2
Этот вопрос даже не близок к предложенному дубликату, пожалуйста, удалите атрибут дублирования. Спасибо.
Daniel Leiszen

Ответы:

147

Вот логика, заключенная в метод расширения:

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

Применение:

var s = "abcdefg";

Console.WriteLine(s.Truncate(3));
Брайан Уоттс
источник
1
Спасибо, Брайан. Ваш ответ выглядит хорошо. Прошу прощения за мой простой вопрос, но как мне использовать метод расширения?
Melony
1
@Melony: отредактировано, чтобы включить использование.
Брайан Уоттс,
11
… (Многоточие) - правильный символ для тех, кому не все равно. Юникод U + 2026.
Malako
3
быстрое дополнение, включающее нулевую проверку
Джеймс
1
спасибо @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;
}

Не обращайте внимания на соглашение об именах, это на тот случай, если ему действительно нужна переменная THRESHOLD или если она всегда одного размера.

Альтернативно

string res = (myStr.Length > THRESHOLD) ? myStr.Substring(0, THRESHOLD) + ".." : myStr;
Хесус Рамос
источник
Можно ли превратить это во что-то одной строкой, которую я мог бы использовать встроенной?
Melony
2
Это может привести к появлению недопустимых строк, если он разделит код посередине :(
CodesInChaos
8

Все очень хорошие ответы, но чтобы немного поправить, если ваши строки являются предложениями, не рвите строку посередине слова.

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;
}
Дж. Стивенс
источник
Это единственный ответ, который не разбивает слов. Поэтому единственно правильный ИМО.
mxmissile
@mxmissile - учитывая данные OP, для "abcdefg", усечение до 3 символов, переходит к "abc ...", даже если бы это сработало, это было бы совсем неправильно. Данные образца OP четко указывают на резкое усечение в середине непрерывного текста. Что еще хуже, этот ответ приведет к ошибке. Поскольку данные не содержат пробелов, LastIndexOfфункция вернет -1 и Substringвызовет ошибку времени выполнения.
4

Вот версия, которая учитывает длину эллипсов:

    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
если вы используете символ многоточия, то в этом нет необходимости. Длина символа всегда будет 1const char ellipse = (char)0x2026;
Пьер
3

В .NET Framework нет встроенного метода, который бы это делал, однако это очень простой метод, который можно написать самостоятельно. Вот шаги, попробуйте сделать это сами и сообщите нам, что вы придумали.

  1. Создайте метод, возможно, метод расширения public static void TruncateWithEllipsis(this string value, int maxLength)

  2. Проверьте, не превышает ли переданное значение значение, maxLengthуказанное с помощью Lengthсвойства . Если valueне больше maxLength, просто верните value.

  3. Если мы не вернули переданное значение как есть, значит, мы знаем, что нам нужно усечь. Таким образом, нам нужно получить меньшую часть строки с помощью SubStringметода . Этот метод вернет меньшую часть строки на основе указанного начального и конечного значения. Конечная позиция - это то, что было передано maxLengthпараметром, поэтому используйте это.

  4. Верните часть строки плюс многоточие.

Отличным упражнением на будущее было бы обновить метод и заставить его останавливаться только после полных слов. Вы также можете создать перегрузку, чтобы указать, как вы хотите, чтобы строка была усечена. Например, метод может возвращать «(щелкните, чтобы узнать больше)» вместо «...», если ваше приложение настроено так, чтобы отображать более подробную информацию при нажатии.

Боб
источник
2

Код позади:

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

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

    return s;
}

Разметка:

<td><%= shorten(YOUR_STRING_HERE) %></td>
VMAtm
источник
Как я мог уместить это в: "<td>" + string + "<\ td>"?
Melony
2

Может быть, лучше реализовать для этого метод:

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

Вы можете использовать функцию подстроки.

Джетро
источник
1

Я нашел этот вопрос после поиска по запросу "усечение многоточия C #". Используя различные ответы, я создал собственное решение со следующими функциями:

  1. Метод расширения
  2. Добавить многоточие
  3. Сделайте многоточие необязательным
  4. Убедитесь, что строка не пуста и не пуста, прежде чем пытаться ее обрезать.

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

Надеюсь, это поможет кому-то другому.

Тод Бердсолл
источник
0

Конечно, вот пример кода:

string str = "abcdefg";
if (str.Length > X){
   str = str.Substring(0, X) + "...";
}
Джастин Этье
источник
0

У меня недавно возникла эта проблема. Я хранил сообщение «статус» в поле базы данных nvarcharMAX, которое составляет 4000 символов. Однако мои статусные сообщения накапливались и вызывали исключение.

Но это был непростой случай усечения, так как произвольное усечение лишило бы часть сообщения статуса, поэтому мне действительно нужно было «усечь» согласованную часть строки.

Я решил проблему, преобразовав строку в массив строк, удалив первый элемент, а затем восстановив строку. Вот код («CurrentStatus» - это строка, содержащая данные) ...

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


        }

Надеюсь, это кому-то поможет.

Даррен-стрит
источник