Как обрезать строку .NET?
Я хотел бы обрезать строку таким образом, чтобы ее длина не превышала заданное значение. Я пишу в таблицу базы данных и хочу убедиться, что значения, которые я пишу, соответствуют ограничению типа данных столбца.
Например, было бы неплохо, если бы я мог написать следующее:
string NormalizeLength(string value, int maxLength)
{
return value.Substring(0, maxLength);
}
К сожалению, это вызывает исключение, поскольку maxLength
обычно превышает границы строки value
. Конечно, я мог бы написать функцию, подобную следующей, но я надеялся, что что-то подобное уже существует.
string NormalizeLength(string value, int maxLength)
{
return value.Length <= maxLength ? value : value.Substring(0, maxLength);
}
Где неуловимый API, который выполняет эту задачу? Есть один?
Ответы
Ответ 1
К сожалению, не существует метода Truncate()
в строке.. Вы должны сами написать эту логику. Однако вы можете сделать это в методе расширения, поэтому вам не нужно его дублировать повсюду:
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);
}
}
Теперь мы можем написать:
var someString = "...";
someString = someString.Truncate(2);
Ответ 2
Или вместо тернарного оператора вы можете использовать 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));
}
}
Ответ 3
Я подумал, что я бы бросил свою реализацию, так как я считаю, что он охватывает все случаи, которые затронули другие, и делает это в сжатом виде, который все еще доступен для чтения.
public static string Truncate(this string value, int maxLength)
{
if (!string.IsNullOrEmpty(value) && value.Length > maxLength)
{
return value.Substring(0, maxLength);
}
return value;
}
Это решение в основном основывается на Ray решении и открывает метод для использования в качестве метода расширения, используя это ключевое слово, как Л.Бушкин делает в своем решении.
Ответ 4
В .NET 4.0 вы можете использовать метод Take
:
string.Concat(myString.Take(maxLength));
Не проверено на эффективность!
Ответ 5
Вы можете использовать LINQ... это устраняет необходимость проверки длины строки. По общему признанию, может быть, не самый эффективный, но это весело.
string result = string.Join("", value.Take(maxLength)); // .NET 4 Join
или
string result = new string(value.Take(maxLength).ToArray());
Ответ 6
Потому что тестирование производительности это весело: (используя методы расширения 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();
Метод truncate
был "значительно" быстрее. #microoptimization
Рано
- truncate10 Прошло 5788 тиков (0,5788 мс) [за 10 000 повторений, 5,788E-05 мс за]
- smart-trunc10 истекло 8206 тактов (0,8206 мс) [в 10 000 повторений, 8,206E-05 мс за]
- stringbuilder10 Прошло 10557 тактов (1,0557 мс) [за 10 000 повторений, 0,00010557 мс за]
- concat10 Прошло 45495 тактов (4,5495 мс) [в 10 000 повторений, 0,00045495 мс за]
- newstring10 72535 тактов прошло (7,2535 мс) [в 10 000 повторений, 0,00072535 мс на]
поздно
- truncate44 Прошло 8835 тактов (0,8835 мс) [в 10 000 повторений, 8,835E-05 мс за]
- stringbuilder44 Прошло 13106 тактов (1,3106 мс) [за 10 000 повторений, 0,00013106 мс за]
- smart-trunc44 Прошло 14821 тактов (1,4821 мс) [в 10 000 повторений, 0,00014821 мс за]
- newstring44 144324 тактов прошло (14,4324 мс) [за 10 000 повторений, 0,00144324 мс за]
- concat44 Прошло 174610 тиков (17,461 мс) [за 10 тысяч повторений, 0,0017461 мс за]
Слишком долго
- smart-trunc64 Прошло 6944 такта (0,6944 мс) [за 10 000 повторений, 6,944E-05 мс за]
- truncate64 Прошло 7686 тиков (0,7686 мс) [за 10 000 повторений, 7,686E-05 мс за]
- stringbuilder64 Прошло 13314 тактов (1,3314 мс) [в 10 000 повторений, 0,00013314 мс за]
- newstring64 Прошло 177481 тактов (17,7481 мс) [за 10 000 повторений, 0,00177481 мс за]
- concat64 Прошло 241601 тактов (24,1601 мс) [в 10 000 повторений, 0,00241601 мс за]
Ответ 7
Кажется, никто еще не опубликовал это сообщение:
public static class StringExt
{
public static string Truncate(this string s, int maxLength)
{
return s != null && s.Length > maxLength ? s.Substring(0, maxLength) : s;
}
}
Использование && оператор делает его немного лучше, чем принятый ответ.
Ответ 8
.NET Framework имеет API для обрезания строки следующим образом:
Microsoft.VisualBasic.Strings.Left(string, int);
Но в приложении С# вы, вероятно, предпочтете использовать свой собственный, нежели зависимо от Microsoft.VisualBasic.dll, чья основная ценность - обратная совместимость.
Ответ 9
Я сделал в одной строке вроде этого
value = value.Length > 1000 ? value.Substring(0, 1000) : value;
Ответ 10
Я знаю, что это старый вопрос, но вот хорошее решение:
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);
Возвращает: привет...
Ответ 11
Аналогичный вариант с С# 6 Оператор Null распространения
public static string Truncate(this string value, int maxLength)
{
return value?.Length <= maxLength ? value : value?.Substring(0, maxLength);
}
Обратите внимание, что мы по существу проверяем, является ли value
здесь два раза.
Ответ 12
По-прежнему нет метода Truncate в 2016 году для строк С#.
Но - с помощью синтаксиса С# 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);
}
}
Он работает как шарм:
"Truncate me".Truncate(8);
Result: "Truncate"
Ответ 13
Другое решение:
return input.Substring(0, Math.Min(input.Length, maxLength));
Ответ 14
Взятие @CaffGeek и его упрощение:
public static string Truncate(this string value, int maxLength)
{
return string.IsNullOrEmpty(value) ? value : value.Substring(0, Math.Min(value.Length, maxLength));
}
Ответ 15
Обратите внимание, что усечение строки не просто означает, что вырезаете строку только по определенной длине, но должны позаботиться о том, чтобы не разбить слово.
например, строка: это тестовая строка.
Я хочу разрезать его на 11. Если мы будем использовать любой из приведенных выше методов, результат будет
это te
Это не то, что мы хотим
Метод, который я использую, также может быть не настолько совершенным, но он может справиться с большей частью ситуации.
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());
}
Ответ 16
Почему бы и нет:
string NormalizeLength(string value, int maxLength)
{
//check String.IsNullOrEmpty(value) and act on it.
return value.PadRight(maxLength).Substring(0, maxLength);
}
то есть. в случае value.Length < maxLength
пробелов пробела до конца или усечения избытка.
Ответ 17
На всякий случай здесь недостаточно ответов, здесь моя:)
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;
}
для использования:
"I use it like this".Truncate(5,"~")
Ответ 18
Для большей сложности я добавлю свою перегруженную версию, которая заменяет последние 3 символа эллипсисом в отношении параметра maxLength.
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));
}
Ответ 19
Я предпочитаю jpierson answer, но ни один из примеров, которые я вижу, не обрабатывает недопустимый параметр maxLength, например, когда maxLength < 0.
Выбор будет либо обрабатывать ошибку в try/catch, закрепить параметр maxLength min до 0, либо maxLength меньше 0 возвращает пустую строку.
Не оптимизированный код:
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;
}
Ответ 20
Вот решение vb.net, отметьте, что оператор if (хотя и уродливый) повышает производительность, потому что нам не нужен оператор подстроки, когда строка уже меньше, чем maxlength...
Сделав его расширением до строки, он прост в использовании...
<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
Ответ 21
Я знаю, что есть тонна ответов, но мне нужно было сохранить начало и конец строки неповрежденными, но сократить ее до максимальной длины.
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));
}
Это для создания URL-адресов SharePoint, длина которых не превышает 260 символов.
Я не задал длину параметра, так как он является константой 260. Я также не сделал первую длину подстроки a параметром, потому что я хочу, чтобы она разбилась на определенную точку. Наконец, вторая подстрока - это длина источника - 20, так как я знаю структуру папок.
Это может быть легко адаптировано к вашим конкретным потребностям.
Ответ 22
Я знаю, что здесь уже есть тонна ответов, но это тот, с которым я ушел, который обрабатывает как нулевые строки, так и ситуацию, когда передаваемая длина отрицательна:
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);
}
Ответ 23
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;
}
Ответ 24
В дополнение к рассмотренным выше возможностям я хотел бы поделиться своим решением. Это метод расширения, который позволяет null (возвращает string.Empty), и есть второй .Truncate() для его использования с многоточием. Осторожно, это не оптимизированная производительность.
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);
Ответ 25
Мои два цента с примером длины 30:
var truncatedInput = string.IsNullOrEmpty(input) ?
string.Empty :
input.Substring(0, Math.Min(input.Length, 30));
Ответ 26
В этом нет ничего в .net, о котором я знаю - вот моя версия, которая добавляет "...":
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;
}
}
Ответ 27
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
}
Ответ 28
Я бы рекомендовал использовать метод подстроки для той же эффективной функциональности.
// Gets first n characters.
string subString = inputString.Substring(0, n);
Преимущество этого состоит в том, что вы можете сращивать вашу строку с любой стороны или даже где-то посередине без написания дополнительных методов. Надеюсь, это поможет :)
Для дополнительной справки: https://www.dotnetperls.com/substring
Ответ 29
Обрезать строку
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 "";
}
}
Ответ 30
Это код, который я обычно использую:
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();
}