2010-12-02 11 views
47

Estoy buscando métodos de extensión de cadena para TrimStart() y TrimEnd() que acepten un parámetro de cadena.C# TrimStart con el parámetro de cadena

Yo podría construir uno yo mismo, pero siempre estoy interesado en ver cómo otras personas hacen cosas.

¿Cómo se puede hacer esto?

+3

Tu pregunta no es muy clara. ¿Qué debería hacer exactamente el parámetro de cadena en una función de recorte? (Suponiendo que no se está refiriendo a la sintaxis obligatoria de 'esta cadena' del método de extensión) – asawyer

+1

Así que quiere dos funciones con la misma funcionalidad que TrimStart/TrimEnd | ¿O quieres uno que quite los caracteres de entrada del principio/final? – Blam

+0

Sí, la misma funcionalidad que TrimStart y TrimEnd, pero acepta una cadena en lugar de una char. –

Respuesta

66

TrimStart:

public static string TrimStart(this string target, string trimChars) 
{ 
    return target.TrimStart(trimChars.ToCharArray()); 
} 

TrimEnd:

public static string TrimEnd(this string target, string trimChars) 
{ 
    return target.TrimEnd(trimChars.ToCharArray()); 
} 

Tenga en cuenta que esta función será recortar cualquier de los personajes de trimChars desde el principio/final de destino, por ejemplo, "foobar;'@".TrimEnd(";@'") volverá "foobar"

Si por el contrario la intención es cortar todas las ocurrencias de la cadena (que coincide exactamente), entonces debería usar algo como lo siguiente:

TrimStart:

public static string TrimStart(this string target, string trimString) 
{ 
    string result = target; 
    while (result.StartsWith(trimString)) 
    { 
     result = result.Substring(trimString.Length); 
    } 

    return result; 
} 

TrimEnd:

public static string TrimEnd(this string target, string trimString) 
{ 
    string result = target; 
    while (result.EndsWith(trimString)) 
    { 
     result = result.Substring(0, result.Length - trimString.Length); 
    } 

    return result; 
} 
+13

Esta no es una buena solución ya que también recorta una coincidencia parcial: "foobartes" .TrimEnd ("prueba" .ToCharArray()) da como resultado foobar. Imho solo debería recortar si obtienes una coincidencia exacta. editar: quickfix: agregar un target.EndsWith (trimChars) comprobar antes de recortar – Contra

+0

de acuerdo, esto no suena como lo que el operador estaba solicitando. Estaba bajo la suposición de que querían recortar una cuerda determinada desde el principio de una cuerda más grande. Simplemente TrimStarting todos los caracteres en la cadena podría eliminar los casos donde no coincide exactamente. – Tim

+2

Gracias por la sugerencia 'string.ToCharArray()'. –

16

TrimStart y TrimEnd tienen una gran variedad de caracteres. Esto significa que se puede pasar en una cadena como una matriz de caracteres así:

var trimChars = " .+-"; 
var trimmed = myString.TrimStart(trimChars.ToCharArray()); 

Así que no ven la necesidad de una sobrecarga que toma un parámetro de cadena.

+1

Guau, eso es embarazoso. No me di cuenta que así fue como funcionó. ¡Gracias! –

+4

Tenga en cuenta que esta solución coincide con los caracteres de recorte en ** cualquier orden **. Por ejemplo, si 'myString =" Sammy "' y 'trimChars =" Sam "' devolverá '" y ", pero el resultado esperado es" my ". Por lo tanto, recorta demasiado y no considera la palabra de ajuste como tal. – Matt

-1

Supongo que quiere decir que, por ejemplo, dada la cadena "HelloWorld" y llamando a la función para "recortar" el comienzo con "Hola", se quedaría con "Mundo". Yo diría que esto es realmente una operación de subcadenas, ya que está eliminando una parte de la cadena de longitud conocida, en lugar de una operación de recorte que elimina una longitud de cadena desconocida.

Como tal, creamos un par de métodos de extensión llamados SubstringAfter y SubstringBefore. Sería bueno tenerlos en el marco, pero no es así, es necesario que los implementen ustedes mismos. No olvide tener un parámetro StringComparison, y usar Ordinal como predeterminado si lo hace opcional.

-1

Si quiere una que no use las funciones de recorte integradas por cualquier motivo, suponiendo que quiere una cadena de entrada para recortar, como "~!" siendo esencialmente el mismo que el construido en TrimStart con ['', '~', '!']

public static String TrimStart(this string inp, string chars) 
{ 
    while(chars.Contains(inp[0])) 
    { 
     inp = inp.Substring(1); 
    } 

    return inp; 
} 

public static String TrimEnd(this string inp, string chars) 
{ 
    while (chars.Contains(inp[inp.Length-1])) 
    { 
     inp = inp.Substring(0, inp.Length-1); 
    } 

    return inp; 
} 
8

pensé que la cuestión estaba tratando de cortar una cadena específica desde el inicio de una cadena más grande.

Por ejemplo, si tuviera la cadena "hellohellogoodbyehello", si intentas llamar a TrimStart ("hola") obtendrás "goodbyehello".

Si ese es el caso, se puede utilizar código como el siguiente:

string TrimStart(string source, string toTrim) 
{ 
    string s = source; 
    while (s.StartsWith(toTrim)) 
    { 
     s = s.Substring(toTrim.Length - 1); 
    } 
    return s; 
} 

esto no sería súper eficiente si necesita hacer un montón de cuerdas de poda, pero si es sólo por algunos casos, es simple y hace el trabajo.

+0

Esto debería ser 'toTrim.length', sin el' -1' ¿correcto? –

3

de dotnetperls.com,

Rendimiento

Por desgracia, el método TrimStart no está muy optimizado. En situaciones específicas de , es probable que pueda escribir el código de iteración basado en caracteres que puede superarlo. Esto se debe a que se debe crear una matriz para usar TrimStart.

Sin embargo, el código personalizado no requiere necesariamente una matriz. Pero para las aplicaciones de desarrollo rápido , el método TrimStart es útil.

+0

¿Y cómo se puede implementar? Creo que esa fue la pregunta. – Matt

0

No hay función incorporada en C#, pero puede escribir sus propias extensiones que se comporten exactamente de la manera esperada.

Tenga en cuenta que con IndexOf/LastIndexOf, puede elegir si es sensible a las mayúsculas/minúsculas o no.

Implementé también la función "ajustes repetitivos".

Hay una función TrimStr(..) tratar con ambos ajustes, además de tres funciones de ejecución .TrimStart(...), .TrimEnd(...) y .Trim(..) para la compatibilidad con .NET recorta:

Try it in DotNetFiddle

public static class Extension 
{ 
    public static string TrimStr(this string str, string trimStr, 
        bool trimEnd = true, bool repeatTrim = true, 
        StringComparison comparisonType = StringComparison.OrdinalIgnoreCase) 
    { 
     int strLen; 
     do 
     { 
      if (!(str ?? "").EndsWith(trimStr)) return str; 
      strLen = str.Length; 
      { 
      if (trimEnd) 
       { 
        var pos = str.LastIndexOf(trimStr, comparisonType); 
        if ((!(pos >= 0)) || (!(str.Length - trimStr.Length == pos))) break; 
        str = str.Substring(0, pos); 
       } 
       else 
       { 
        var pos = str.IndexOf(trimStr, comparisonType); 
        if (!(pos == 0)) break; 
        str = str.Substring(trimStr.Length, str.Length - trimStr.Length); 
       } 
      } 
     } while (repeatTrim && strLen > str.Length); 
     return str; 
    } 

    // the following is C#6 syntax, if you're not using C#6 yet 
    // replace "=> ..." by { return ... } 

    public static string TrimEnd(this string str, string trimStr, 
      bool repeatTrim = true, 
      StringComparison comparisonType = StringComparison.OrdinalIgnoreCase) 
      => TrimStr(str, trimStr, true, repeatTrim, comparisonType); 

    public static string TrimStart(this string str, string trimStr, 
      bool repeatTrim = true, 
      StringComparison comparisonType = StringComparison.OrdinalIgnoreCase) 
      => TrimStr(str, trimStr, false, repeatTrim, comparisonType); 

    public static string Trim(this string str, string trimStr, bool repeatTrim = true, 
     StringComparison comparisonType = StringComparison.OrdinalIgnoreCase) 
     => str.TrimStart(trimStr, repeatTrim, comparisonType) 
       .TrimEnd(trimStr, repeatTrim, comparisonType); 

} 

Ahora sólo se puede utilizar es como

Console.WriteLine("Sammy".TrimEnd("my")); 
    Console.WriteLine("moinmoin gibts gips? gips gibts moin".TrimStart("moin", false)); 
    Console.WriteLine("moinmoin gibts gips? gips gibts moin".Trim("moin").Trim()); 

que crea la salida

Sam
gibts moin de yeso? gips gibts moin
gibts gips? gips gibts

+0

Tenga en cuenta que TrimStr es utilizado internamente por Trim, TrimStart y TrimEnd. – Matt

+0

La diferencia es que puede usar TrimStr para decidir a través del parámetro si desea un ajuste desde el inicio o desde el final de la cadena. – Matt

Cuestiones relacionadas