Làm thế nào để tôi cắt một chuỗi .NET?


406

Tôi muốn cắt một chuỗi sao cho độ dài của nó không dài hơn một giá trị đã cho. Tôi đang viết vào một bảng cơ sở dữ liệu và muốn đảm bảo rằng các giá trị tôi viết đáp ứng ràng buộc của kiểu dữ liệu của cột.

Ví dụ, thật tuyệt nếu tôi có thể viết như sau:

string NormalizeLength(string value, int maxLength)
{
    return value.Substring(0, maxLength);
}

Thật không may, điều này làm tăng một ngoại lệ vì maxLengththường vượt quá ranh giới của chuỗi value. Tất nhiên, tôi có thể viết một hàm như sau, nhưng tôi đã hy vọng rằng một cái gì đó như thế này đã tồn tại.

string NormalizeLength(string value, int maxLength)
{
    return value.Length <= maxLength ? value : value.Substring(0, maxLength);
} 

API khó nắm bắt thực hiện nhiệm vụ này ở đâu? Có một cái không?


24
Đối với bản ghi, các chuỗi là bất biến bạn không thể cắt bớt chúng, bạn chỉ có thể trả lại một bản sao bị cắt ngắn của chúng. Nitpicky, tôi biết.
John Weldon

2
@ John Weldon: Có lẽ đó là lý do tại sao hàm thành viên không tồn tại - nó không tuân theo ngữ nghĩa của kiểu dữ liệu. Mặt khác, StringBuildercho phép bạn cắt ngắn bằng cách rút ngắn độ dài, nhưng bạn vẫn cần thực hiện kiểm tra độ dài để tránh mở rộng chuỗi.
Steve Guidi

1
Cho dù bạn chọn giải pháp nào, hãy chắc chắn thêm một kiểm tra cho chuỗi null trước khi gọi Chuỗi con hoặc truy cập thuộc tính Độ dài.
Ray

3
@SteveGuidi - Nếu đó là trường hợp, thì sẽ không có các chức năng như Trim hoặc Thay thế, đối mặt với các vấn đề ngữ nghĩa tương tự
Chris Rogers

1
@JohnWeldon nitpicky Hơn Microsoft tự luôn là, khi nó xảy ra - họ đang hạnh phúc để tài liệu, ví dụ, .Trim()trong một cách mà làm cho nó sai lạc âm thanh như nó đột biến chuỗi: "Loại bỏ tất cả các ký tự trắng-không gian ở đầu và đuôi từ đối tượng String hiện tại. "
Mark Amery

Câu trả lời:


620

Truncate()Thật không may, một phương thức trên chuỗi, thật không may. Bạn phải tự viết loại logic này. Tuy nhiên, những gì bạn có thể làm là gói nó trong một phương thức mở rộng để bạn không phải sao chép nó ở mọi nơi:

public static class StringExt
{
    public static string Truncate(this string value, int maxLength)
    {
        if (string.IsNullOrEmpty(value)) return value;
        return value.Length <= maxLength ? value : value.Substring(0, maxLength); 
    }
}

Bây giờ chúng ta có thể viết:

var someString = "...";
someString = someString.Truncate(2);

5
Giải pháp tuyệt vời, nhưng hãy nhớ điều này chỉ hoạt động trong NET 3.5 trở lên. Đừng thử nó trong NET2.0.
Jedi Master Spooky

7
Miễn là bạn ở VS 2008 và có lẽ là VS 2010, bạn vẫn có thể làm điều này ngay cả khi nhắm mục tiêu .Net 2.0. danielmoth.com/Blog/ Kẻ
Đánh dấu

4
Điều này sẽ thất bại khi maxLengthlà một giá trị âm.
Bernard

42
@Bernard, điều này được cho là thất bại nếu maxLpm âm. Bất kỳ hành vi khác sẽ là bất ngờ.
bojingo

12
Bạn có thể gọi các phương thức mở rộng trên các giá trị null.
Joel Malone

127

Hoặc thay vì toán tử ternary, bạn có thể sử dụng Math.min

public static class StringExt
{
    public static string Truncate( this string value, int maxLength )
    {
        if (string.IsNullOrEmpty(value)) { return value; }

        return value.Substring(0, Math.Min(value.Length, maxLength));
    }
}

10
Tài giỏi! Và biểu thức sau đây được tối ưu hóa để trả về một tham chiếu đến chuỗi gốc : value.Substring(0, value.Length).
Steve Guidi

4
Thật không may, nó không được tối ưu hóa cho các trường hợp có giá trị. Độ dài nhỏ hơn MaxLpm có thể là trường hợp phổ biến trong một số dữ liệu. Ngoài ra, thuộc tính Độ dài trên chuỗi nên được viết hoa.
jpierson

1
Điều này sẽ thất bại khi maxLengthlà một giá trị âm.
Bernard

7
@Bernard, như vậy sẽ rất nhiều thứ trong khuôn khổ ... nhưng nếu tôi kiểm tra cho nó ... tôi hoặc là phải mặc định maxLengthđể 0hay value.Length; hoặc tôi cần ném một ArgumentOutOfRangeException... có ý nghĩa hơn trong trường hợp này, và Substringdù sao cũng đã bị ném .
CaffGeek

2
return string.IsNullOrEmpty(value) ? value : value.Substring(0, Math.Min(value.Length, maxLength));
Ngắn

43

Tôi hình dung rằng tôi sẽ thực hiện việc triển khai của mình vì tôi tin rằng nó bao gồm tất cả các trường hợp đã được người khác chạm vào và thực hiện theo cách ngắn gọn mà vẫn có thể đọc được.

public static string Truncate(this string value, int maxLength)
{
    if (!string.IsNullOrEmpty(value) && value.Length > maxLength)
    {
        return value.Substring(0, maxLength);
    }

    return value;
}

Giải pháp này chủ yếu dựa trên giải pháp của Ray và mở ra phương thức sử dụng làm phương pháp mở rộng bằng cách sử dụng từ khóa này giống như LBushkin làm trong giải pháp của mình.


Điều này sẽ thất bại khi maxLengthlà một giá trị âm.
Bernard

15
@Bernard - Tôi khuyên bạn không nên chuyển một giá trị âm cho đối số maxLạng vì nó là một giá trị không mong muốn. Phương thức chuỗi con có cách tiếp cận tương tự vì vậy không có lý do gì để cải thiện ngoại lệ mà nó ném.
jpierson

Tôi không nghĩ rằng kiểm tra IsNullOrEmpty là cần thiết? (1) Nếu giá trị là null, sẽ không có cách nào để gọi phương thức mở rộng này trên đó. (2) Nếu giá trị là chuỗi rỗng, kiểm tra giá trị. Độ dài> tối đa sẽ thất bại.
Jon Schneider

8
@JonSchneider, IsNullOrEmpty là bắt buộc vì đây là phương thức mở rộng. Nếu bạn có một biến kiểu chuỗi đã được gán null, trình biên dịch sẽ không chèn kiểm tra null trước khi gọi phương thức này. Về mặt kỹ thuật, đây vẫn là một phương thức tĩnh của lớp tĩnh. Vì vậy: stringVar.Truncate (2) Biên dịch thành: StringExt.Truncate (stringVar, 2);
Jeff B

40

Bởi vì thử nghiệm hiệu năng rất thú vị: (sử dụng các phương pháp mở rộng linqpad )

var val = string.Concat(Enumerable.Range(0, 50).Select(i => i % 10));

foreach(var limit in new[] { 10, 25, 44, 64 })
    new Perf<string> {
        { "newstring" + limit, n => new string(val.Take(limit).ToArray()) },
        { "concat" + limit, n => string.Concat(val.Take(limit)) },
        { "truncate" + limit, n => val.Substring(0, Math.Min(val.Length, limit)) },
        { "smart-trunc" + limit, n => val.Length <= limit ? val : val.Substring(0, limit) },
        { "stringbuilder" + limit, n => new StringBuilder(val, 0, Math.Min(val.Length, limit), limit).ToString() },
    }.Vs();

Các truncatephương pháp là "đáng kể" nhanh hơn. #microoptimization

Sớm

  • truncate10 5788 tick đã trôi qua (0,5788 ms) [trong 10 nghìn đại diện, 5,788E-05 ms mỗi lần]
  • thông minh-trunc10 8206 tick đã trôi qua (0.8206 ms) [trong 10K reps, 8.206E-05 ms mỗi]
  • Stringbuilder10 10557 tick trôi qua (1.0557 ms) [trong 10K reps, 0,00010557 ms mỗi]
  • concat10 45495 tick đã trôi qua (4.5495 ms) [trong 10K reps, 0,00045495 ms mỗi]
  • newopes10 72535 tick đã trôi qua (7.2535 ms) [trong 10K reps, 0,00072535 ms mỗi]

Muộn

  • truncate44 8835 tick đã trôi qua (0,8835 ms) [trong 10K reps, 8,835E-05 ms mỗi]
  • Stringbuilder44 13106 tick đã trôi qua (1.3106 ms) [trong 10K reps, 0,00013106 ms mỗi]
  • thông minh-trunc44 14821 tick đã trôi qua (1.4821 ms) [trong 10K reps, 0,00014821 ms mỗi]
  • newopes44 144324 tick đã trôi qua (14.4324 ms) [trong 10K reps, 0,00144324 ms mỗi]
  • concat44 174610 tick đã trôi qua (17.461 ms) [trong 10K reps, 0,0017461 ms mỗi]

Quá lâu

  • thông minh trunc64 6944 đã trôi qua (0,6944 ms) [trong 10 nghìn đại diện, 6,944E-05 ms mỗi lần]
  • truncate64 7686 tick đã trôi qua (0,7686 ms) [trong 10K reps, 7.686E-05 ms mỗi]
  • Stringbuilder64 13314 tick đã trôi qua (1.3314 ms) [trong 10K reps, 0,00013314 ms mỗi]
  • newopes64 177481 tick trôi qua (17,7481 ms) [trong 10K reps, 0,00177481 ms mỗi]
  • concat64 241601 tick đã trôi qua (24.1601 ms) [trong 10K reps, 0,00241601 ms mỗi]

Cảm ơn tất cả các điểm chuẩn hữu ích! ... và Linkpad đá!
Sunsetquest

đừng bận tâm rằng linqpad có thể làm những việc đó
jefissu

38

Trong .NET 4.0, bạn có thể sử dụng Takephương thức:

string.Concat(myString.Take(maxLength));

Không được kiểm tra về hiệu quả!


27

Bạn có thể sử dụng LINQ ... nó giúp loại bỏ sự cần thiết phải kiểm tra độ dài chuỗi. Phải thừa nhận rằng có thể không hiệu quả nhất, nhưng nó rất vui.

string result = string.Join("", value.Take(maxLength)); // .NET 4 Join

hoặc là

string result = new string(value.Take(maxLength).ToArray());

2
Tại sao đây không phải là câu trả lời được chấp nhận? Điều gì là thẳng thắn nhất, viết phương pháp Tiện ích mở rộng của riêng bạn mà bạn cần duy trì / tài liệu hoặc sử dụng một cái gì đó BUILT IN như .Take
Don Cheadle

9
@mmcrae Linq có thể thẳng hơn, nhưng nó cũng chậm hơn rất nhiều. Điểm chuẩn của tôi cho biết ~ 400ms cho Linq và chỉ ~ 24ms cho Chuỗi con cho 1 triệu lần lặp.
Hein Andre Grønnestad

Giải pháp này không nên được sử dụng. Như đã nói trong hai ý kiến ​​trên, luôn có sự phân bổ bộ nhớ, ngay cả khi chuỗi hiện tại không lớn hơn độ dài tối đa. Ngoài ra, nó rất chậm.
Kamarey

15

Tôi đã làm của tôi trong một dòng như thế này

value = value.Length > 1000 ? value.Substring(0, 1000) : value;

2
-1; điều này không thêm bất cứ điều gì chưa có trong câu trả lời được chấp nhận.
Mark Amery

2
@markamery đó là một sự thay thế ngắn hơn với ít mã hơn để viết và cập nhật khi bạn cần sử dụng nó. Đừng như vậy? Đừng sử dụng nó
SeanMC

Nhanh chóng, đơn giản và nhanh chóng. Đây là những gì tôi cần. Cảm ơn!
Peter

14

Có vẻ như chưa có ai đăng bài này:

public static class StringExt
{
    public static string Truncate(this string s, int maxLength)
    {
        return s != null && s.Length > maxLength ? s.Substring(0, maxLength) : s;
    }
}

Sử dụng toán tử && làm cho nó tốt hơn một chút so với câu trả lời được chấp nhận.


13

.NET Framework có API để cắt một chuỗi như thế này:

Microsoft.VisualBasic.Strings.Left(string, int);

Nhưng trong ứng dụng C #, có lẽ bạn sẽ thích tự lăn hơn là phụ thuộc vào Microsoft.VisualBasic.dll, người có khả năng tương thích chính là khả năng tương thích ngược.


".NET Framework có API" bạn đang mâu thuẫn với chính mình. Đó là API VB.NET
Camilo Terevinto

9
@CamiloTerevinto - đó là một API được phân phối với .NET Framework và có thể được gọi từ bất kỳ ngôn ngữ được quản lý nào.
Joe

1
VB DLL có rất nhiều thứ tốt trong đó. Tại sao có nhiều c # dev chống lại nó?
Michael Z.

Không có hỗ trợ .NET Core hiện tại, thật không may. Thật vậy, toàn bộ Microsoft.VisualBasic.Stringscác mô-đun trong .NET Core khá trống rỗng .
Mark Amery

1
Mặc dù tôi đồng ý với nhận xét của Joe, tôi vẫn không cảm thấy đúng khi gọi một cái gì đó cụ thể cho VB từ các ngôn ngữ khác. Nếu có quá nhiều thứ hay ho trong "VB DLL", tại sao bạn không đặt nó ở một nơi nào đó? Ai biết Microsoft sẽ làm gì với những thứ này vào ngày mai? Dừng hỗ trợ hoặc một cái gì đó ..
Kamarey


6

Tôi biết đây là một câu hỏi cũ, nhưng đây là một giải pháp hay:

public static string Truncate(this string text, int maxLength, string suffix = "...")
{
    string str = text;
    if (maxLength > 0)
    {
        int length = maxLength - suffix.Length;
        if (length <= 0)
        {
            return str;
        }
        if ((text != null) && (text.Length > maxLength))
        {
            return (text.Substring(0, length).TrimEnd(new char[0]) + suffix);
        }
    }
    return str;
}

var myString = "hello world"
var myTruncatedString = myString.Truncate(4);

Trả về: xin chào ...


@SarjanWebDev Nhân vật đặc biệt đó xuất hiện dưới dạng "." trong cmd.exe
Neal Ehardt

5

Một biến thể tương tự với toán tử lan truyền Null của C # 6

public static string Truncate(this string value, int maxLength)
{
    return value?.Length <= maxLength ? value : value?.Substring(0, maxLength);
}

Xin lưu ý, về cơ bản chúng tôi đang kiểm tra nếu valuenull hai lần ở đây.


5

Vẫn không có phương pháp Truncate trong năm 2016 cho chuỗi C #. Nhưng - Sử dụng Cú pháp C # 6.0:

public static class StringExtension
{
  public static string Truncate(this string s, int max) 
  { 
    return s?.Length > max ? s.Substring(0, max) : s ?? throw new ArgumentNullException(s); 
  }
}

Nó hoạt động như một say mê:

"Truncate me".Truncate(8);
Result: "Truncate"

4

Lấy @CaffGeek và đơn giản hóa nó:

public static string Truncate(this string value, int maxLength)
    {
        return string.IsNullOrEmpty(value) ? value : value.Substring(0, Math.Min(value.Length, maxLength));
    }

4

Kndly lưu ý rằng việc cắt một chuỗi không chỉ đơn thuần có nghĩa là chỉ cắt một chuỗi ở một độ dài xác định mà còn phải cẩn thận không tách từ.

ví dụ: chuỗi: đây là chuỗi thử nghiệm.

Tôi muốn cắt nó ở 11. Nếu chúng ta sử dụng bất kỳ phương pháp nào được đưa ra ở trên, kết quả sẽ là

đây là một te

Đây không phải là điều chúng tôi muốn

Phương pháp tôi đang sử dụng có thể không quá hoàn hảo nhưng nó có thể xử lý hầu hết các tình huống

public string CutString(string source, int length)
{
        if (source== null || source.Length < length)
        {
            return source;
        }
        int nextSpace = source.LastIndexOf(" ", length);
        return string.Format("{0}...", input.Substring(0, (nextSpace > 0) ? nextSpace : length).Trim());
} 

4

Tại sao không:

string NormalizeLength(string value, int maxLength)
{
    //check String.IsNullOrEmpty(value) and act on it. 
    return value.PadRight(maxLength).Substring(0, maxLength);
}

tức là trong value.Length < maxLengthkhông gian pad sự kiện đến cuối hoặc cắt bớt phần thừa.


Bạn tạo gấp đôi số đối tượng chuỗi và nó có thể ném NullReferenceException từ lệnh gọi PadRight nếu giá trị là null không phù hợp, đó phải là một ArgumentNullException.
Jeremy

1
@Jeremy Tôi không hiểu "nó có thể ném NullReferenceException từ lệnh gọi PadRight nếu giá trị là null"; Tôi đã không đề cập "// kiểm tra chuỗi.IsNullOrEmpty (giá trị) và hành động theo nó."
Sri

3

Chỉ trong trường hợp không có đủ câu trả lời ở đây, đây là của tôi :)

public static string Truncate(this string str, 
                              int totalLength, 
                              string truncationIndicator = "")
{
    if (string.IsNullOrEmpty(str) || str.Length < totalLength) 
        return str;

    return str.Substring(0, totalLength - truncationIndicator.Length) 
           + truncationIndicator;
}

sử dụng:

"I use it like this".Truncate(5,"~")

2

Vì sự phức tạp (hơn), tôi sẽ thêm phiên bản quá tải của mình, thay thế 3 ký tự cuối cùng bằng dấu chấm lửng đối với tham số maxLạng.

public static string Truncate(this string value, int maxLength, bool replaceTruncatedCharWithEllipsis = false)
{
    if (replaceTruncatedCharWithEllipsis && maxLength <= 3)
        throw new ArgumentOutOfRangeException("maxLength",
            "maxLength should be greater than three when replacing with an ellipsis.");

    if (String.IsNullOrWhiteSpace(value)) 
        return String.Empty;

    if (replaceTruncatedCharWithEllipsis &&
        value.Length > maxLength)
    {
        return value.Substring(0, maxLength - 3) + "...";
    }

    return value.Substring(0, Math.Min(value.Length, maxLength)); 
}

2

Hai xu của tôi với chiều dài ví dụ là 30:

  var truncatedInput = string.IsNullOrEmpty(input) ? 
      string.Empty : 
      input.Substring(0, Math.Min(input.Length, 30));

1

Tôi thích câu trả lời của jpierson, nhưng không có ví dụ nào ở đây mà tôi có thể thấy đang xử lý một tham số maxLpm không hợp lệ, chẳng hạn như khi maxLpm <0.

Các lựa chọn sẽ xử lý lỗi trong một lần thử / bắt, kẹp tham số maxLpm tối thiểu thành 0 hoặc nếu maxLpm nhỏ hơn 0 trả về một chuỗi trống.

Mã không được tối ưu hóa:

public string Truncate(this string value, int maximumLength)
{
    if (string.IsNullOrEmpty(value) == true) { return value; }
    if (maximumLen < 0) { return String.Empty; }
    if (value.Length > maximumLength) { return value.Substring(0, maximumLength); }
    return value;
}

3
Lưu ý, trong quá trình triển khai của tôi, tôi đã chọn không xử lý trường hợp trong đó MaximumLimum nhỏ hơn 0 vì tôi nghĩ rằng điều duy nhất tôi sẽ làm là ném một ArgumentOutOfRangeExcpetion mà về cơ bản là chuỗi nào.Sub chuỗi () làm cho tôi.
jpierson

1

Đây là một giải pháp vb.net, đánh dấu rằng câu lệnh if (mặc dù xấu) cải thiện hiệu năng vì chúng ta không cần câu lệnh chuỗi con khi chuỗi đã nhỏ hơn maxlength ... Bằng cách làm cho nó trở thành một chuỗi mở rộng, nó rất dễ sử dụng. ..

 <System.Runtime.CompilerServices.Extension()> _
    Public Function Truncate(String__1 As String, maxlength As Integer) As String
        If Not String.IsNullOrEmpty(String__1) AndAlso String__1.Length > maxlength Then
            Return String__1.Substring(0, maxlength)
        Else
            Return String__1
        End If
    End Function

Trong VB.net, bạn có thể thay thế "Không phải String.IsNullOrEmpty (String__1)" bằng "String__1 <> nothing". Nó ngắn hơn một chút. Giá trị mặc định cho chuỗi là một chuỗi rỗng. Sử dụng "<> Không có gì" kiểm tra cả null và các trường hợp chuỗi rỗng. Kiểm tra thử với: Truncate ("", 50) và Truncate (nothing, 50)
jrjensen

Trong VB, bạn có thể thực hiện Trái (chuỗi, maxlength)
Michael Z.

1

Tôi biết đã có rất nhiều câu trả lời nhưng nhu cầu của tôi là giữ nguyên đầu và cuối của chuỗi nhưng rút ngắn nó xuống dưới độ dài tối đa.

    public static string TruncateMiddle(string source)
    {
        if (String.IsNullOrWhiteSpace(source) || source.Length < 260) 
            return source;

        return string.Format("{0}...{1}", 
            source.Substring(0, 235),
            source.Substring(source.Length - 20));
    }

Điều này là để tạo URL SharePoint có độ dài tối đa 260 ký tự.

Tôi đã không tạo độ dài cho một tham số vì nó là hằng số 260. Tôi cũng không biến độ dài chuỗi con đầu tiên thành tham số vì tôi muốn nó bị phá vỡ tại một điểm cụ thể. Cuối cùng, chuỗi con thứ hai là độ dài của nguồn - 20 kể từ khi tôi biết cấu trúc thư mục.

Điều này có thể dễ dàng thích nghi với nhu cầu cụ thể của bạn.


1

Tôi biết đã có rất nhiều câu trả lời ở đây, nhưng đây là câu trả lời tôi đã xử lý, xử lý cả chuỗi null và tình huống độ dài được truyền vào là âm:

public static string Truncate(this string s, int length)
{
    return string.IsNullOrEmpty(s) || s.Length <= length ? s 
        : length <= 0 ? string.Empty 
        : s.Substring(0, length);
}

1

Trong C # 8, tính năng Phạm vi mới có thể được sử dụng ...

value = value[..Math.Min(30, value.Length)];

0

Không có gì trong .net cho điều này mà tôi biết - đây là phiên bản của tôi có thêm "...":

public static string truncateString(string originalString, int length) {
  if (string.IsNullOrEmpty(originalString)) {
   return originalString;
  }
  if (originalString.Length > length) {
   return originalString.Substring(0, length) + "...";
  }
  else {
   return originalString;
  }
}

2
Phiên bản của bạn sẽ cung cấp các chuỗi dài hơn 3 ký tự so với độ dài được yêu cầu, trong trường hợp chúng bị cắt ngắn. Bên cạnh đó, ba dấu chấm thực sự chỉ có ý nghĩa trong đại diện, tôi sẽ không lưu trữ nó trong cơ sở dữ liệu giống như trường hợp sử dụng mà OP đã đưa ra.
MarioDS

0

TruncateString

public static string _TruncateString(string input, int charaterlimit)
{
    int characterLimit = charaterlimit;
    string output = input;

    // Check if the string is longer than the allowed amount
    // otherwise do nothing
    if (output.Length > characterLimit && characterLimit > 0)
    {
        // cut the string down to the maximum number of characters
        output = output.Substring(0, characterLimit);
        // Check if the character right after the truncate point was a space
        // if not, we are in the middle of a word and need to remove the rest of it
        if (input.Substring(output.Length, 1) != " ")
        {
            int LastSpace = output.LastIndexOf(" ");

            // if we found a space then, cut back to that space
            if (LastSpace != -1)
            {
                output = output.Substring(0, LastSpace);
            }
        }
        // Finally, add the "..."
        output += "...";
    }
    return output;
}

2
Tại sao bạn lại đặt trước tên phương thức công khai của mình bằng dấu gạch dưới?
Michael Z.

0

Ngoài ra, tôi cũng muốn chia sẻ giải pháp của mình. Đây là một phương thức mở rộng cho phép null (trả về chuỗi.Empty) cũng có một .Truncate () thứ hai để sử dụng nó với dấu chấm lửng. Coi chừng, nó không được tối ưu hóa hiệu suất.

public static string Truncate(this string value, int maxLength) =>
    (value ?? string.Empty).Substring(0, (value?.Length ?? 0) <= (maxLength < 0 ? 0 : maxLength) ? (value?.Length ?? 0) : (maxLength < 0 ? 0 : maxLength));
public static string Truncate(this string value, int maxLength, string ellipsis) =>
    string.Concat(value.Truncate(maxLength - (((value?.Length ?? 0) > maxLength ? ellipsis : null)?.Length ?? 0)), ((value?.Length ?? 0) > maxLength ? ellipsis : null)).Truncate(maxLength);

-1
public static string Truncate( this string value, int maxLength )
    {
        if (string.IsNullOrEmpty(value)) { return value; }

        return new string(value.Take(maxLength).ToArray());// use LINQ and be happy
    }

Cuộc ToArray()gọi ở đây chỉ là không cần thiết; bằng cách sử dụng, ví dụ String.Concatbạn có thể xây dựng một chuỗi từ vô số ký tự mà không cần phải đi qua một mảng.
Mark Amery

-3

Chuỗi cắt

public static string TruncateText(string strText, int intLength)
{
    if (!(string.IsNullOrEmpty(strText)))
    {                                
        // split the text.
        var words = strText.Split(' ');

        // calculate the number of words
        // based on the provided characters length 
        // use an average of 7.6 chars per word.
        int wordLength = Convert.ToInt32(Math.Ceiling(intLength / 7.6));

        // if the text is shorter than the length,
        // display the text without changing it.
        if (words.Length <= wordLength)
            return strText.Trim();                

        // put together a shorter text
        // based on the number of words
        return string.Join(" ", words.Take(wordLength)) + " ...".Trim();
    }
        else
        {
            return "";
        }            
    }

Điều này không trả lời câu hỏi của OP. Đầu tiên, nó phải là một hàm thành viên (mặc dù bạn đã viết nó như một phương thức mở rộng). Thứ hai, OP không chỉ định rằng văn bản phải được phân chia và các từ đã được cắt ngắn để xấp xỉ. 7.6 ký tự mỗi từ.
Visser giàu hơn

7.6 chỉ là một con số. bạn có thể viết bất kỳ số nào bạn muốn. Điều này đã xảy ra là một chiều dài từ tiếng Anh trung bình. Tôi tìm thấy nó trên google. Sử dụng phân tách chỉ là một cách dễ dàng để chia nhỏ các từ theo không gian. Tôi không nghĩ rằng bạn muốn hiển thị một nửa từ! Vì vậy, trừ khi bạn lặp qua để tìm không gian trống sẽ yêu cầu nhiều mã hơn, đây là cách dễ dàng để cắt một chuỗi và hiển thị các từ đầy đủ. Điều này sẽ đảm bảo cho bạn rằng một chuỗi không dài hơn độ dài cho trước và bạn sẽ không có từ bị hỏng.
VT

-4

Đây là mã tôi thường sử dụng:

string getSubString(string value, int index, int length)
        {
            if (string.IsNullOrEmpty(value) || value.Length <= length)
            {
                return value;
            }
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            for (int i = index; i < length; i++)
            {
                sb.AppendLine(value[i].ToString());
            }
            return sb.ToString();
        }

5
Xin lưu ý rằng các chuỗi nối với + = là một hoạt động đắt tiền, đặc biệt là khi xây dựng lại ký tự theo từng ký tự. Chuỗi .NET là bất biến, có nghĩa là trong trường hợp này, một chuỗi mới được tạo mỗi lần trong vòng lặp của bạn.
Steve Guidi

Chuỗi @SteveGuidi không phải là bất biến, họ chỉ giả trang là bất biến. Tôi ước chuỗi là các nguyên thủy bất biến thực sự để tôi có thể có chuỗi và chuỗi?, Nhưng than ôi chúng không phải là nguyên thủy.
Chris Marisic

Bạn nói đắt như thể chi phí hiệu năng là đáng kể, tôi đã thay đổi nó để sử dụng chuỗiBuilder nhưng tôi thấy rằng với + = thì dễ thấy điều gì đang xảy ra, tôi chỉ muốn OP dễ dàng hiểu mã.
dùng3390116
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.