.net 在C#中,从字符串的开头删除所有可能的空白字符和自定义字符的最佳方法是什么?

iecba09b  于 2023-05-01  发布在  .NET
关注(0)|答案(3)|浏览(240)

在C#中,我想Trim()所有可能类型的空格字符串的两端(如定义)。IsWhitespace),并修剪字符串的开头,以同时从char[]数组中的自定义列表中删除出现在常规字母数字字符之前的任何字符。所以字符串的结尾应该是第一个字符不是空格,也不是我的自定义列表中的字符。(但是,字符串当然可以在第一个字符之后包含空格或字符。)
我只想遍历字符串一次来完成所有这些操作,因为有一个很大的字符串列表要修剪。
下面的代码不起作用(请参阅代码片段下面的更多注解)。

static class TrimmerExtension
    {
        private const string _prefixCharsToTrimAsString = "~`$|-_";
        private static readonly char[] _prefixCharsToTrim;

        // static ctor
        static TrimmerExtension()
        {
            _prefixCharsToTrim = _prefixCharsToTrimAsString.ToCharArray();
        }

        public static string TrimWhitespaceAndPrefixes(this string s)
        {
            return s.Trim().TrimStart(_prefixCharsToTrim).TrimStart();
        }
    }

上面的方法不起作用,因为:
1.它多次调用不同版本的Trim,从而多次迭代字符串。(所以上面是低效的);
1.如果要修剪的其他字符之间存在空格字符,则它不会从开始就完全修剪所有空格和特殊字符;例如,如果字符串包含“$ ~ Something”,则扩展方法将返回“~ Something”,但仍需要删除前两个字符。(以上代码不正确。)
C#或。NET提供了一种有效的方法来做到这一点(在性能和源代码简单性方面)?或者,是否有一个类或库定义了一个常量字符(或字符串)数组,其中包含Trim()函数将从字符串中删除的所有可能的空格字符,以便我可以将其添加到要删除的特殊前缀字符列表中?
如果这个特定的问题已经回答,请发布一个链接到问题和答案(S)。
谢谢。

sqserrrh

sqserrrh1#

看起来没有简单的方法,因为string.Trim()内部使用了两种不同的方法。
用于空白的TrimWhiteSpaceHelper:

private string TrimWhiteSpaceHelper(TrimType trimType)
    {
        // end will point to the first non-trimmed character on the right.
        // start will point to the first non-trimmed character on the left.
        int end = Length - 1;
        int start = 0;

        // Trim specified characters.
        if ((trimType & TrimType.Head) != 0)
        {
            for (start = 0; start < Length; start++)
            {
                if (!char.IsWhiteSpace(this[start]))
                {
                    break;
                }
            }
        }

        if ((trimType & TrimType.Tail) != 0)
        {
            for (end = Length - 1; end >= start; end--)
            {
                if (!char.IsWhiteSpace(this[end]))
                {
                    break;
                }
            }
        }

        return CreateTrimmedString(start, end);
    }

和TrimHelper用于自定义字符:

private unsafe string TrimHelper(char* trimChars, int trimCharsLength, TrimType trimType)
    {
        Debug.Assert(trimChars != null);
        Debug.Assert(trimCharsLength > 0);

        // end will point to the first non-trimmed character on the right.
        // start will point to the first non-trimmed character on the left.
        int end = Length - 1;
        int start = 0;

        // Trim specified characters.
        if ((trimType & TrimType.Head) != 0)
        {
            for (start = 0; start < Length; start++)
            {
                int i = 0;
                char ch = this[start];
                for (i = 0; i < trimCharsLength; i++)
                {
                    if (trimChars[i] == ch)
                    {
                        break;
                    }
                }
                if (i == trimCharsLength)
                {
                    // The character is not in trimChars, so stop trimming.
                    break;
                }
            }
        }

        if ((trimType & TrimType.Tail) != 0)
        {
            for (end = Length - 1; end >= start; end--)
            {
                int i = 0;
                char ch = this[end];
                for (i = 0; i < trimCharsLength; i++)
                {
                    if (trimChars[i] == ch)
                    {
                        break;
                    }
                }
                if (i == trimCharsLength)
                {
                    // The character is not in trimChars, so stop trimming.
                    break;
                }
            }
        }

        return CreateTrimmedString(start, end);
    }

将它们组合起来可能看起来像这样:

public static class TrimmerExtension
{
    public static string TrimWhitespaceAndPrefixes(this string str, params char[] trimChars)
    {
        var trimCharsLength = trimChars.Length;
        int start;
        for (start = 0; start < str.Length; start++)
        {
            var ch = str[start];
            if (!char.IsWhiteSpace(ch))
            {
                int i;
                for (i = 0; i < trimCharsLength; i++)
                {
                    if (trimChars[i] == ch)
                    {
                        break;
                    }
                }

                if (i == trimCharsLength)
                {
                    break;
                }
            }
        }

        return str[start..];
    }
}

如果性能不是很重要,我建议使用正则表达式或https://stackoverflow.com/a/76133168/2770274的简写版本

dvtswwa3

dvtswwa32#

为什么不用手呢?

public static string MySpecialTrim(string str, char[] trimChars)
{
    for (var i = 0; i < str.Length; ++i)
    {
        char ch = str[i];
        if (!char.IsWhiteSpace(ch) && !trimChars.Contains(ch))              
            return str.Substring(i);
    }
    return str;
}

这样您就可以控制哪些角色被修剪。

cczfrluj

cczfrluj3#

  • 可以使用TrimStart()
  • 它将从当前字符串中删除所有前导空白字符。
  • 你也可以传递你想从字符串的前导中删除的字符数组。
  • 例如,你想从字符串前导中删除空格$和百分比,你可以这样做?
string input = "$%Hello World";

char[] trimChars = {' ', '$', '%'};

string output = input.TrimStart(trimChars);

Console.WriteLine(output); // Output: "Hello World"
  • 要从字符串末尾删除,可以使用TrimEnd()
    *有关TrimStartTrimEnd的更多信息。

相关问题