String类中的哪个方法仅返回前N个字符?


184

我想为String该类编写一个扩展方法,以便如果to的输入字符串长于提供的长度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

Answers:


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知道如果第二个参数大于长度,那么它只是插入了长度?
马丁2010年

12
我相信它是:System.String.InternalSubStringWithChecks会抛出ArgumentOutOfRange。
Paul Ruane 2010年

2
@马丁:不是我所看到的,startIndex > (this.Length - length)抛出一个ArgumentOutOfRangeException
user7116 2010年

2
我打算建议检查一下Math.Min(str.Length, maxLength) == str.Length,以防万一您最终创建了一个不必要的字符串以返回“ str的第一个str.Length字符”,但是Substring会为您进行检查,return this如果您要求输入整个字符串,则也会这样做。
stevemegson

2
如果您希望扩展方法在可能为空的字符串上工作...返回str?.Substring(0,Math.Min(str.Length,maxLength));
ihake

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

这个解决方案有一个很小的好处,就是如果n大于s.Length,它仍然会做正确的事情。


9
是的,但是使用Linq截断字符串吗?请注意,如果多次使用(例如在循环中),这将导致非常糟糕的表现。不要习惯性地这样做
ErikE '18年

31

您可以使用LINQ str.Take(n)str.SubString(0, n),后者会为抛出ArgumentOutOfRangeException异常n > str.Length

注意LINQ版本返回a IEnumerable<char>,因此您必须将转换IEnumerable<char>stringnew string(s.Take(n).ToArray())


10
不要使用Linq截断字符串。这是荒谬的。
ErikE

17

每当我必须使用C#进行字符串操作时,我都会想念Visual Basic中的旧版本LeftRight函数,它们比起来更容易使用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; }
Grandizer

str需要检查为空
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,2010年

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有什么问题?
Muflix '18 -10-5

1

我在项目中添加了它只是因为我在网上托管的项目中很有可能在循环中使用它,因此如果我能够管理它,我就不会崩溃。长度适合我的一列。这是C#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年5月在以下网站上发布了有关此内容的博客:http//jagdale.blogspot.com/2010/05/substring-extension-method-that-does.html


0

部分出于概述的目的(不包括LINQ解决方案),这里有两个单行代码,它们说明int maxLength了允许使用负值的注意事项以及空字符串的情况:

  1. Substring方法(从保罗·鲁安的答案):
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
与公认的答案不同,这可能导致索引超出范围错误。
Servy 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.