c# - remove - ¿Cómo trunco una cadena.NET?
truncate string java (28)
Me gustaría truncar una cadena para que su longitud no sea más larga que un valor dado. Estoy escribiendo en una tabla de base de datos y quiero asegurarme de que los valores que escribo cumplan con la restricción del tipo de datos de la columna.
Por ejemplo, sería bueno si pudiera escribir lo siguiente:
string NormalizeLength(string value, int maxLength)
{
return value.Substring(0, maxLength);
}
Desafortunadamente, esto genera una excepción porque maxLength
generalmente excede los límites del value
de la cadena. Por supuesto, podría escribir una función como la siguiente, pero esperaba que algo así ya existiera.
string NormalizeLength(string value, int maxLength)
{
return value.Length <= maxLength ? value : value.Substring(0, maxLength);
}
¿Dónde está la API esquiva que realiza esta tarea? Hay uno
.NET Framework tiene una API para truncar una cadena como esta:
Microsoft.VisualBasic.Strings.Left(string, int);
Pero en una aplicación de C # probablemente prefiera rodar su propia cuenta que tomar una dependencia en Microsoft.VisualBasic.dll, cuya principal razón de ser es la compatibilidad con versiones anteriores.
Aún no hay un método Truncate en 2016 para las cadenas C #. Pero - usando la sintaxis de 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);
}
}
Funciona a las mil maravillas:
"Truncate me".Truncate(8);
Result: "Truncate"
Aquí hay una solución vb.net, marque que la instrucción if (aunque fea) mejora el rendimiento porque no necesitamos la instrucción subcadena cuando la cadena ya es más pequeña que maxlength ... Al hacerlo una extensión de la cadena es fácil de usar. ..
<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
Cadena truncada
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();
}
Como una adición a las posibilidades discutidas anteriormente, me gustaría compartir mi solución. Es un método de extensión que permite null (devuelve string.Empty) y también hay un segundo .Truncate () para usarlo con puntos suspensivos. Cuidado, no es el rendimiento optimizado.
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;
}
}
En .NET 4.0 puedes usar el método Take
:
string.Concat(myString.Take(maxLength));
No probado para la eficiencia!
En aras de la complejidad (excesiva), agregaré mi versión sobrecargada que reemplaza los últimos 3 caracteres con puntos suspensivos con respecto al parámetro 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));
}
Este es el código que suelo usar:
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(); }
Hice el mío en una línea como esta
value = value.Length > 1000 ? value.Substring(0, 1000) : value;
No hay nada en .net para esto que yo sepa, aquí está mi versión que agrega "...":
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
}
O en lugar del operador ternario, puede usar 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));
}
}
Parece que nadie ha publicado esto todavía:
public static class StringExt
{
public static string Truncate(this string s, int maxLength)
{
return s != null && s.Length > maxLength ? s.Substring(0, maxLength) : s;
}
}
Usar el operador && lo hace marginalmente mejor que la respuesta aceptada.
Pensé que incluiría mi implementación ya que creo que cubre todos los casos que han sido abordados por los demás y lo hace de una manera concisa que todavía es legible.
public static string Truncate(this string value, int maxLength)
{
if (!string.IsNullOrEmpty(value) && value.Length > maxLength)
{
return value.Substring(0, maxLength);
}
return value;
}
Esta solución se basa principalmente en la solución de Ray y abre el método para usarlo como un método de extensión mediante el uso de esta palabra clave tal como lo hace LBushkin en su solución.
Podría usar LINQ ... elimina la necesidad de verificar la longitud de la cadena. Es cierto que quizás no sea el más eficiente, pero es divertido.
string result = string.Join("", value.Take(maxLength)); // .NET 4 Join
o
string result = new string(value.Take(maxLength).ToArray());
Por qué no:
string NormalizeLength(string value, int maxLength)
{
//check String.IsNullOrEmpty(value) and act on it.
return value.PadRight(maxLength).Substring(0, maxLength);
}
es decir, en el valor del evento. value.Length < maxLength
rellena los espacios hasta el final o trunca el exceso.
Por si acaso no hay suficientes respuestas aquí, aquí está la mía :)
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;
}
usar:
"I use it like this".Truncate(5,"~")
Porque las pruebas de rendimiento son divertidas: (usando los métodos de extensión de 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();
El método truncate
fue "significativamente" más rápido. #microoptimización
Temprano
- truncate10 5788 ticks transcurridos (0.5788 ms) [en 10K reps, 5.788E-05 ms por]
- smart-trunc10 8206 ticks transcurridos (0.8206 ms) [en 10K reps, 8.206E-05 ms por]
- stringbuilder10 10557 ticks transcurridos (1.0557 ms) [en 10K reps, 0.00010557 ms por]
- concat10 45495 ticks transcurridos (4.5495 ms) [en 10K reps, 0.00045495 ms por]
- newstring10 72535 ticks transcurridos (7.2535 ms) [en 10K reps, 0.00072535 ms por]
Tarde
- truncate44 8835 ticks transcurridos (0.8835 ms) [en 10K reps, 8.835E-05 ms por]
- stringbuilder44 13106 ticks transcurridos (1.3106 ms) [en 10K reps, 0.00013106 ms por]
- smart-trunc44 14821 ticks transcurridos (1.4821 ms) [en 10K reps, 0.00014821 ms por]
- newstring44 144324 ticks transcurridos (14.4324 ms) [en 10K reps, 0.00144324 ms por]
- concat44 174610 ticks transcurridos (17.461 ms) [en 10K reps, 0.0017461 ms por]
Demasiado largo
- smart-trunc64 6944 ticks transcurridos (0.6944 ms) [en 10K reps, 6.944E-05 ms por]
- truncate64 7686 ticks transcurridos (0.7686 ms) [en 10K reps, 7.686E-05 ms por]
- stringbuilder64 13314 ticks transcurridos (1.3314 ms) [en 10K reps, 0.00013314 ms por]
- newstring64 177481 ticks transcurridos (17.7481 ms) [en 10K reps, 0.00177481 ms por]
- concat64 241601 ticks transcurridos (24.1601 ms) [en 10K reps, 0.00241601 ms por]
Prefiero la respuesta de jpierson, pero ninguno de los ejemplos aquí que puedo ver están manejando un parámetro maxLength no válido, como cuando maxLength <0.
Las opciones serían manejar el error en un try / catch, fijar el parámetro maxLength min a 0, o si maxLength es menor que 0 devuelve una cadena vacía.
Código no optimizado:
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;
}
Recomiendo usar el método de subcadena para la misma funcionalidad efectiva.
// Gets first n characters.
string subString = inputString.Substring(0, n);
Esto tiene la ventaja de permitirle unir su cadena desde cualquier lado o incluso en algún punto intermedio sin escribir métodos adicionales. Espero que ayude :)
Para referencia adicional: https://www.dotnetperls.com/substring
Sé que esta es una vieja pregunta, pero aquí hay una buena solución:
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);
Devoluciones: hola ...
Sé que ya hay un montón de respuestas aquí, pero esta es la que he seguido, que maneja ambas cadenas nulas y la situación en la que la longitud pasada es negativa:
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);
}
Sé que ya hay un montón de respuestas, pero mi necesidad era mantener intactos el principio y el final de la cadena, pero acortarla por debajo de la longitud máxima.
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));
}
Esto es para crear direcciones URL de SharePoint que tienen una longitud máxima de 260 caracteres.
No hice de la longitud un parámetro, ya que es una constante de 260. Tampoco hice de la primera subcadena un parámetro porque quiero que se rompa en un punto específico. Finalmente, la segunda subcadena es la longitud de la fuente - 20 ya que conozco la estructura de la carpeta.
Esto podría adaptarse fácilmente a sus necesidades específicas.
Tenga en cuenta que truncar una cadena no significa simplemente cortar una cuerda en una longitud específica, sino que debe tener cuidado de no dividir la palabra.
Ej .: cadena: esta es una cadena de prueba.
Quiero cortarlo a las 11. Si usamos cualquiera de los métodos dados anteriormente, el resultado será
esto es un te
Esto no es lo que queremos
El método que estoy usando puede que no sea tan perfecto pero puede manejar la mayor parte de la situación
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());
}
Tomando @CaffGeek y simplificándolo:
public static string Truncate(this string value, int maxLength)
{
return string.IsNullOrEmpty(value) ? value : value.Substring(0, Math.Min(value.Length, maxLength));
}
Una variante similar con el operador de propagación nula de C # 6
public static string Truncate(this string value, int maxLength)
{
return value?.Length <= maxLength ? value : value?.Substring(0, maxLength);
}
Tenga en cuenta que básicamente estamos comprobando si el value
es nulo dos veces aquí.
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;
}
Desafortunadamente, no hay un método Truncate()
en la cadena. Tienes que escribir este tipo de lógica tú mismo. Sin embargo, lo que puede hacer es envolver esto en un método de extensión para que no tenga que duplicarlo en todas partes:
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);
}
}
Ahora podemos escribir:
var someString = "...";
someString = someString.Truncate(2);
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 "";
}
}