Подтвердить что ты не робот

Строка обрезать из конца строки в .NET - почему это отсутствует?

Мне это нужно все время, и я постоянно разочаровываюсь в том, что функции Trim(), TrimStart() и TrimEnd() не принимают строки в качестве входных данных. Вы вызываете EndsWith() в строке и выясняете, заканчивается ли она другой строкой, но если вы хотите удалить ее с конца, вам нужно сделать подстроки для этого (или вызвать Remove() и молить единственный экземпляр...)

Почему эта основная функция отсутствует в .NET? И, во-вторых, любые рекомендации для простого способа реализации этого (предпочтительно не для маршрута регулярного выражения...)

4b9b3361

Ответ 1

TrimEnd() (и другие методы обрезки) принимают символы для обрезки, но не строки. Если вы действительно хотите версию, которая может обрезать целые строки, вы можете создать метод расширения. Например...

public static string TrimEnd(this string input, string suffixToRemove,
    StringComparison comparisonType) {

    if (input != null && suffixToRemove != null
      && input.EndsWith(suffixToRemove, comparisonType)) {
        return input.Substring(0, input.Length - suffixToRemove.Length);
    }
    else return input;
}

Это может быть вызвано так же, как встроенные методы.

Ответ 2

EDIT - завернутый в удобный метод расширения:

public static string TrimEnd(this string source, string value)
{
    if (!source.EndsWith(value))
        return source;

    return source.Remove(source.LastIndexOf(value));
}

чтобы вы могли просто сделать s = s.TrimEnd("DEF");

Ответ 3

Использование кода Дэниела и его перенос через некоторое время, а не прямой if дает функциональность, более близкую к функции Microsoft Trim:

public static string TrimEnd(this string input, string suffixToRemove)
{
    while (input != null && suffixToRemove != null && input.EndsWith(suffixToRemove))
    {
        input = input.Substring(0, input.Length - suffixToRemove.Length);
    }
    return input;
}

Ответ 4

Я выбил этот быстрый метод расширения.

Не положительно это работает (я не могу проверить это прямо сейчас), но теория звучит.

    public static string RemoveLast(this string source, string value)
    {
        int index = source.LastIndexOf(value);
        return index != -1 ? source.Remove(index, value.Length) : source;
    }

Ответ 5

Заменить Regex может быть ваш друг в этом случае.

var str = "Hello World!";
str = Regex.Replace(str, @"World!$", "");
//str == "Hello"

Ответ 6

Мне нравится, что TrimEnd удаляет все экземпляры строки в конце, а не только последнюю.

public static string TrimEnd(this string str, string trimStr)
{
    if (string.IsNullOrEmpty(str) || string.IsNullOrEmpty(trimStr)) return str;

    while(str.EndsWith(trimStr))
    {
        str = str.Remove(str.LastIndexOf(trimStr));
    }
    return str;
}

Ответ 7

Это то, против чего вы не согласны?

if (theString.endsWith(theOtherString))
{
   theString = theString.Substring(0, theString.Length - theOtherString.Length);
}

Ответ 8

Trim(), TrimStart() и TrimEnd() - это методы, которые заменяют все вхождения одного и того же символа. Это означает, что вы можете удалить только серию пробелов или ряд точек, например.

Вы можете использовать замену регулярного выражения, чтобы выполнить это:

string s1 = "This is a sentence.TRIMTHIS";
string s2 = System.Text.RegularExpressions.Regex.Replace(s1, @"TRIMTHIS$", "");

Вы можете обернуть его в методе расширения для удобства:

public static string TrimStringEnd(this string text, string removeThis)
{
    return System.Text.RegularExpressions.Regex.Replace(s1, removeThis, "");
}

И назовите это так

string s2 = (@"This is a sentence.TRIMTHIS").TrimStringEnd(@"TRIMTHIS");

Ответ 9

В этом методе расширения я придумал (тяжелое вдохновение из существующих ответов на этот вопрос) в дополнение к существующему методу TrimEnd; он принимает необязательный параметр bool, позволяющий удалить только один завершающий экземпляр строки вместо всех завершающих экземпляров.

/// <summary>
/// Removes trailing occurrence(s) of a given string from the current System.String object.
/// </summary>
/// <param name="trimSuffix">A string to remove from the end of the current System.String object.</param>
/// <param name="removeAll">If true, removes all trailing occurrences of the given suffix; otherwise, just removes the outermost one.</param>
/// <returns>The string that remains after removal of suffix occurrence(s) of the string in the trimSuffix parameter.</returns>
public static string TrimEnd(this string input, string trimSuffix, bool removeAll = true) {
    while (input != null && trimSuffix != null && input.EndsWith(trimSuffix)) {
        input = input.Substring(0, input.Length - trimSuffix.Length);

        if (!removeAll) {
            return input;
        }
    }

    return input;
}

Ответ 10

.TrimStart("AB".ToCharArray())

Ответ 11

Недавно я нуждался в высокопроизводительном способе удаления одного или нескольких экземпляров строки из начала/конца строки. Эта реализация, которую я придумал, представляет собой O (n) для длины строки, избегает дорогостоящих распределений и вообще не вызывает SubString с использованием span.

Нет Substring взломать! (Ну теперь, когда я отредактировал свой пост).

    public static string Trim(this string source, string whatToTrim, int count = -1) 
        => Trim(source, whatToTrim, true, true, count);

    public static string TrimStart(this string source, string whatToTrim, int count = -1) 
        => Trim(source, whatToTrim, true, false, count);

    public static string TrimEnd(this string source, string whatToTrim, int count = -1) 
        => Trim(source, whatToTrim, false, true, count);

    public static string Trim(this string source, string whatToTrim, bool trimStart, bool trimEnd, int numberOfOccurrences)
    {
        // source.IsNotNull(nameof(source));  <-- guard method, define your own
        // whatToTrim.IsNotNull(nameof(whatToTrim));  <-- "

        if (numberOfOccurrences == 0 
            || (!trimStart && !trimEnd) 
            || whatToTrim.Length == 0 
            || source.Length < whatToTrim.Length)
            return source;

        int start = 0, end = source.Length - 1, trimlen = whatToTrim.Length;

        if (trimStart)
            for (int count = 0; start < source.Length; start += trimlen, count++)
            {
                if (numberOfOccurrences > 0 && count == numberOfOccurrences)
                    break;
                for (int i = 0; i < trimlen; i++)
                    if ((source[start + i] != whatToTrim[i] && i != trimlen) || source.Length - start < trimlen)
                        goto DONESTART;
            }

        DONESTART:
        if (trimEnd)
            for (int count = 0; end > -1; end -= trimlen, count++)
            {
                if (numberOfOccurrences != -1 && count == numberOfOccurrences)
                    break;

                for (int i = trimlen - 1; i > -1; --i)
                    if ((source[end - trimlen + i + 1] != whatToTrim[i] && i != 0) || end - start + 1 < trimlen)
                        goto DONEEND;
            }

        DONEEND:
        return source.AsSpan().Slice(start, end - start + 1).ToString();
    }

Ответ 12

В следующем примере показано, как извлекать отдельные слова из блока текста, обрабатывая пробелы и знаки препинания как разделители. Массив символов, переданный параметру separator метода String.Split(Char[]), состоит из символа пробела и символа табуляции вместе с некоторыми обычными символами пунктуации.

string words ="sfdgdfg-121";
string [] split = words.Split(new Char [] {' ', ',', '.', ':', '-' });
foreach (string s in split)
{
    if (s.Trim() != "")              
        Console.WriteLine(s);
}

Попробуйте этот код.

Ответ 13

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

Здесь используется метод, который я использую для этого.

public static string TrimEnd(string input, string suffixToRemove)
{
    if (input == null)
        throw new ArgumentException("input cannot be null.");
    if (suffixToRemove == null)
        throw new ArgumentException("suffixToRemove cannot be null.");
    int pos = input.LastIndexOf(suffixToRemove);
    if (pos == (input.Length - suffixToRemove.Length))
        return input.Substring(0, pos);
    return input;
}

Ответ 14

Попробуйте использовать:

string test = "This is a test, just a test"
test.Split(',')[0];

Это простой и простой способ обрезать строку из строки. Затем вы получаете первый индекс Split, который находится перед char