Який метод у класі String повертає лише перші N символів?


184

Я хотів би написати метод розширення до Stringкласу, так що якщо рядок введення до більше, ніж передбачена довжина N, відображатимуться лише перші Nсимволи.

Ось як це виглядає:

public static string TruncateLongString(this string str, int maxLength)
{
    if (str.Length <= maxLength)
        return str;
    else
        //return the first maxLength characters                
}

Який String.*()метод я можу використовувати, щоб отримати лише перших Nсимволів str?

Відповіді:


374
public static string TruncateLongString(this string str, int maxLength)
{
    if (string.IsNullOrEmpty(str))
        return str;
    return str.Substring(0, Math.Min(str.Length, maxLength));
}

6
Чи потрібен Math.Min? Я думав, що Substring знає, що якщо другий параметр більший за довжину, він просто підключений до довжини?
Мартін

12
Я вважаю, що це: System.String.InternalSubStringWithChecks би кинув ArgumentOutOfRange.
Пол Руан

2
@Martin: не те, що я бачу, startIndex > (this.Length - length)кидає ArgumentOutOfRangeException.
user7116

2
Я збираюся запропонувати перевірити, якщо Math.Min(str.Length, maxLength) == str.Lengthви в кінцевому підсумку створюєте непотрібну рядок, щоб повернути "перші символи str.Length str", але Substring це перевіряє для вас і так само, return thisякщо ви попросили весь рядок.
stevemegson

2
Якщо ви хочете, щоб метод розширення працював на потенційно нульових рядках ... return str? .Substring (0, Math.Min (str.Length, maxLength));
ihake

62
string truncatedToNLength = new string(s.Take(n).ToArray());  

Це рішення має невеликий бонус у тому, що якщо n більше, ніж s.Length, воно все одно робить правильно.


9
Так, але використовуючи Linq для обрізання рядка? Пам'ятайте лише, що це буде дуже погано, якщо використовувати його багато разів, наприклад, у циклі. Не робіть цього за звичкою
ЕрікЕ

31

Ви можете використовувати LINQ str.Take(n)або str.SubString(0, n)там, де останній викине ArgumentOutOfRangeExceptionвиняток n > str.Length.

Розум , що версія LINQ повертає IEnumerable<char>, тому вам доведеться конвертувати IEnumerable<char>в string: new string(s.Take(n).ToArray()).


10
Не використовуйте Linq для обрізання рядків. Це смішно.
ЕрікЕ

17

Щоразу, коли мені доводиться робити стринг-маніпуляції в C #, я пропускаю старі добрі Leftта Rightфункції від Visual Basic, які набагато простіші у використанні, ніж Substring.

Тому в більшості моїх проектів C # я створюю для них методи розширення:

public static class StringExtensions
{
    public static string Left(this string str, int length)
    {
        return str.Substring(0, Math.Min(length, str.Length));
    }

    public static string Right(this string str, int length)
    {
        return str.Substring(str.Length - Math.Min(length, str.Length));
    }
}

Примітка
. Math.MinЧастина є тому, що Substringкидає, ArgumentOutOfRangeExceptionколи довжина вхідного рядка менша, ніж потрібна довжина, як уже згадувалося в деяких коментарях під попередніми відповідями.

Використання:

string longString = "Long String";

// returns "Long";
string left1 = longString.Left(4);

// returns "Long String";
string left2 = longString.Left(100);

Мені це подобається, але якби рядок був коротшим заданої довжини, пробіли не додаватимуться. public static string Left(this string str, int length) { var Result = str.Substring(0, Math.Min(length, str.Length)); return (Result.Length < length) ? Result.PadRight(length) : Result; }
Грандізер

strпотрібно перевірити на null
liviriniu

14

Просто:

public static String Truncate(String input,int maxLength)
{
   if(input.Length > maxLength)
      return input.Substring(0,maxLength);
   return input;
}

7
public static string TruncateLongString(this string str, int maxLength)
{
    return str.Length <= maxLength ? str : str.Remove(maxLength);
}

1
Також зауважте, що ви також можете зробити метод розширення недійсним, змінивши умову наstr == null || str.Length <= maxLength
kbrimington

6
Для тих , хто цікаво чи Removeабо Substringкраще, немає ніякої різниці. Remove(maxLength)просто дзвінки Substring(0,maxLength)після перевірки меж. Що ви віддаєте перевагу, залежить від того, чи вважаєте ви усікання як "взяти перших символів maxLength" або "викиньте все після символів maxLength". Звичайно, це насправді і те, і інше.
stevemegson

5

якщо ми говоримо про валідації також, чому ми не перевірили наявність нульових рядків. Якісь конкретні причини?

Я думаю, що нижче допомога, оскільки IsNullOrEmpty - це метод, визначений системою, і потрійні оператори мають циклічну складність = 1, якщо if () {} else {} має значення 2.

    public static string Truncate(string input, int truncLength)
    {
        return (!String.IsNullOrEmpty(input) && input.Length >= truncLength)
                   ? input.Substring(0, truncLength)
                   : input;
    }

що таке питання з циклічною складністю 2?
Муфлікс

1

Я додав це до свого проекту лише тому, що там, де я його використовую, велика ймовірність його використання в циклі, в проекті, розміщеному в Інтернеті, отже, я не хотів жодних збоїв, якщо міг би ним керувати. Довжина відповідає стовпцю, який у мене є. Це С # 7

Лише один рядок:

 public static string SubStringN(this string Message, int Len = 499) => !String.IsNullOrEmpty(Message) ? (Message.Length >= Len ? Message.Substring(0, Len) : Message) : "";

0

Метод .NET Substring загрожує небезпекою. Я розробив методи розширення, які обробляють найрізноманітніші сценарії. Приємно, що вона зберігає оригінальну поведінку, але коли ви додаєте додатковий параметр "true", тоді він вдається до методу розширення для обробки винятку і повертає найбільш логічні значення на основі індексу та довжини. Наприклад, якщо довжина від’ємна і вважається зворотною. Ви можете переглянути результати тесту з найрізноманітнішими значеннями на скрипці за посиланням: https://dotnetfiddle.net/m1mSH9 . Це дасть вам чітке уявлення про те, як вона розв’язує підрядки.

Я завжди додаю ці методи до всіх своїх проектів, і ніколи не потрібно хвилюватися про порушення коду, тому що щось змінилося, а індекс недійсний. Нижче наведено код.

    public static String Substring(this String val, int startIndex, bool handleIndexException)
    {
        if (!handleIndexException)
        { //handleIndexException is false so call the base method
            return val.Substring(startIndex);
        }
        if (string.IsNullOrEmpty(val))
        {
            return val;
        }
        return val.Substring(startIndex < 0 ? 0 : startIndex > (val.Length - 1) ? val.Length : startIndex);
    }

    public static String Substring(this String val, int startIndex, int length, bool handleIndexException)
    {
        if (!handleIndexException)
        { //handleIndexException is false so call the base method
            return val.Substring(startIndex, length);
        }
        if (string.IsNullOrEmpty(val))
        {
            return val;
        }
        int newfrom, newlth, instrlength = val.Length;
        if (length < 0) //length is negative
        {
            newfrom = startIndex + length;
            newlth = -1 * length;
        }
        else //length is positive
        {
            newfrom = startIndex;
            newlth = length;
        }
        if (newfrom + newlth < 0 || newfrom > instrlength - 1)
        {
            return string.Empty;
        }
        if (newfrom < 0)
        {
            newlth = newfrom + newlth;
            newfrom = 0;
        }
        return val.Substring(newfrom, Math.Min(newlth, instrlength - newfrom));
    }

Я розповів про це ще в травні 2010 року за адресою: http://jagdale.blogspot.com/2010/05/substring-extension-method-that-does.html


0

Частково заради узагальнення (за винятком рішення LINQ), ось два одношарові, які стосуються int maxLengthзастереження щодо дозволу негативних значень, а також випадку з нульовим рядком:

  1. SubstringШлях (від відповіді Павла Ruane в ):
public static string Truncate(this string s, uint maxLength) =>
    s?.Substring(0, Math.Min(s.Length, (int)maxLength));
  1. RemoveШлях (від відповіді kbrimington в ):
public static string Truncate(this string s, uint maxLength) =>
    s?.Length > maxLength ? s.Remove((int)maxLength) : s;


-4

string.Substring (0, n); // 0 - індекс запуску і n - кількість символів


4
На відміну від прийнятої відповіді, це може призвести до помилок індексу поза межами.
Сервіс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.