Phương thức nào trong lớp String chỉ trả về N ký tự đầu tiên?


184

Tôi muốn viết một phương thức mở rộng cho Stringlớp để nếu chuỗi đầu vào dài hơn độ dài được cung cấp N, chỉ các Nký tự đầu tiên được hiển thị.

Đây là cách nó trông như thế nào:

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

Tôi String.*()có thể sử dụng phương pháp nào để chỉ lấy các Nký tự đầu tiên str?

Câu trả lời:


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
Là Math.Min cần thiết? Tôi nghĩ Sub chuỗi biết rằng nếu tham số thứ hai lớn hơn chiều dài, nó chỉ cắm vào chiều dài?
Martin

12
Tôi tin rằng đó là: System.String.IternalSubStringWithChecks sẽ ném ArgumentOutOfRange.
Paul Ruane

2
@Martin: không phải là tôi có thể nhìn thấy, startIndex > (this.Length - length)ném một ArgumentOutOfRangeException.
user7116

2
Tôi sẽ đề nghị kiểm tra xem Math.Min(str.Length, maxLength) == str.Lengthtrong trường hợp bạn kết thúc việc tạo một chuỗi không cần thiết để trả về "các ký tự str. Bước đầu tiên của str", nhưng Chuỗi con sẽ kiểm tra cho bạn và chỉ thực hiện return thisnếu bạn yêu cầu toàn bộ chuỗi.
stevemegson

2
Nếu bạn muốn phương thức mở rộng hoạt động trên các chuỗi có khả năng null ... return str? .Sub chuỗi (0, Math.Min (str.Lạng, maxLạng));
ihake

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

Giải pháp này có một phần thưởng nhỏ ở chỗ nếu n lớn hơn s.Lipse, nó vẫn làm đúng.


9
Vâng, nhưng sử dụng Linq để cắt một chuỗi? Chỉ cần lưu ý điều này sẽ thực hiện rất tệ nếu được sử dụng nhiều lần như trong một vòng lặp. Đừng làm điều này như một vấn đề của thói quen
ErikE

31

Bạn có thể sử dụng LINQ str.Take(n)hoặc str.SubString(0, n), trong đó cái sau sẽ ném ArgumentOutOfRangeExceptionngoại lệ cho n > str.Length.

Lưu ý rằng phiên bản LINQ trả về a IEnumerable<char>, vì vậy bạn phải chuyển đổi IEnumerable<char>thành string: new string(s.Take(n).ToArray()).


10
Đừng sử dụng Linq để cắt chuỗi. Điều đó thật nực cười.
ErikE

17

Bất cứ khi nào tôi phải thực hiện các thao tác chuỗi trong C #, tôi đều bỏ lỡ các chức năng cũ Leftvà tốt Righttừ Visual Basic, việc sử dụng đơn giản hơn nhiều so với Substring.

Vì vậy, trong hầu hết các dự án C # của tôi, tôi tạo các phương thức mở rộng cho chúng:

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

Lưu ý:
Phần Math.Minnày ở đó vì Substringsẽ ném ArgumentOutOfRangeExceptionkhi độ dài của chuỗi đầu vào nhỏ hơn độ dài được yêu cầu, như đã được đề cập trong một số nhận xét dưới các câu trả lời trước.

Sử dụng:

string longString = "Long String";

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

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

Tôi thích điều này, nhưng nếu chuỗi ngắn hơn độ dài cho trước, nó sẽ không nối thêm khoảng trắng. 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

strcần được kiểm tra null
liviriniu

14

Đơn giản:

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
Ngoài ra, lưu ý rằng bạn cũng có thể làm cho phương thức mở rộng trở nên an toàn bằng cách thay đổi điều kiện thànhstr == null || str.Length <= maxLength
kbrimington

6
Đối với bất cứ ai tự hỏi liệu Removehoặc Substringlà tốt hơn, không có sự khác biệt. Remove(maxLength)chỉ gọi Substring(0,maxLength)sau khi kiểm tra một chút giới hạn. Việc bạn thích phụ thuộc vào việc bạn nghĩ về việc cắt ngắn là "lấy các ký tự maxLpm đầu tiên" hay "vứt bỏ mọi thứ sau các ký tự maxLpm". Tất nhiên, nó thực sự là cả hai vì vậy nó tùy thuộc vào bạn.
stevemegson

5

nếu chúng ta đang nói về xác nhận hợp lệ thì tại sao chúng ta chưa kiểm tra các mục nhập chuỗi rỗng. Bất kỳ lý do cụ thể?

Tôi nghĩ cách trợ giúp bên dưới vì IsNullOrEmpty là một phương thức do hệ thống xác định và các toán tử ternary có độ phức tạp cyclomatic = 1 while if () {} khác {} có giá trị 2.

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

một vấn đề với độ phức tạp 2 là gì?
Muflix

1

Tôi đã thêm điều này vào dự án của mình chỉ vì tôi đang sử dụng nó có khả năng cao nó được sử dụng trong các vòng lặp, trong một dự án được lưu trữ trực tuyến do đó tôi không muốn gặp sự cố nếu tôi có thể quản lý nó. Độ dài phù hợp với một cột tôi có. Đó là C # 7

Chỉ một dòng:

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

0

Phương thức Chuỗi con .NET đầy rủi ro. Tôi đã phát triển các phương thức mở rộng xử lý nhiều tình huống khác nhau. Điều tuyệt vời là nó bảo toàn hành vi ban đầu, nhưng khi bạn thêm một tham số "đúng" bổ sung, thì nó sử dụng phương thức mở rộng để xử lý ngoại lệ và trả về các giá trị logic nhất, dựa trên chỉ số và độ dài. Ví dụ: nếu độ dài là âm và đếm ngược. Bạn có thể xem kết quả kiểm tra với nhiều giá trị khác nhau trên fiddle tại: https://dotnetfiddle.net/m1mSH9 . Điều này sẽ cung cấp cho bạn một ý tưởng rõ ràng về cách nó giải quyết các chất nền.

Tôi luôn thêm các phương thức này vào tất cả các dự án của mình và không bao giờ phải lo lắng về việc phá mã, bởi vì có gì đó đã thay đổi và chỉ mục không hợp lệ. Dưới đây là mã.

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

Tôi đã viết về điều này vào tháng 5 năm 2010 tại: http://jagdale.blogspot.com/2010/05/subopes-extension-method-that-does.html


0

Một phần vì mục đích tóm tắt (không bao gồm giải pháp LINQ), đây là hai lớp lót giải quyết int maxLengthcảnh báo cho phép các giá trị âm và cả trường hợp chuỗi null:

  1. Các Substringcách (từ câu trả lời Paul Ruane của ):
public static string Truncate(this string s, uint maxLength) =>
    s?.Substring(0, Math.Min(s.Length, (int)maxLength));
  1. Các Removecách (từ câu trả lời của kbrimington ):
public static string Truncate(this string s, uint maxLength) =>
    s?.Length > maxLength ? s.Remove((int)maxLength) : s;


-4

chuỗi.Sub chuỗi (0, n); // 0 - chỉ mục bắt đầu và n - số ký tự


4
Không giống như câu trả lời được chấp nhận, điều này có thể dẫn đến chỉ số vượt quá giới hạn lỗi.
Phục vụ
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.