Ich suche nach String-Erweiterungsmethoden für TrimStart()und TrimEnd()akzeptiere einen String-Parameter.
Ich könnte selbst eines bauen, aber ich bin immer daran interessiert zu sehen, wie andere Leute Dinge tun.
Wie kann das gemacht werden?
Ich suche nach String-Erweiterungsmethoden für TrimStart()und TrimEnd()akzeptiere einen String-Parameter.
Ich könnte selbst eines bauen, aber ich bin immer daran interessiert zu sehen, wie andere Leute Dinge tun.
Wie kann das gemacht werden?
Antworten:
Um alle Vorkommen der (genau übereinstimmenden) Zeichenfolge zu kürzen, können Sie Folgendes verwenden:
public static string TrimStart(this string target, string trimString)
{
if (string.IsNullOrEmpty(trimString)) return target;
string result = target;
while (result.StartsWith(trimString))
{
result = result.Substring(trimString.Length);
}
return result;
}
public static string TrimEnd(this string target, string trimString)
{
if (string.IsNullOrEmpty(trimString)) return target;
string result = target;
while (result.EndsWith(trimString))
{
result = result.Substring(0, result.Length - trimString.Length);
}
return result;
}
Um eines der Zeichen in trimChars vom Anfang / Ende des Ziels aus zu trimmen (z. B. "foobar'@"@';".TrimEnd(";@'")wird zurückkehren "foobar"), können Sie Folgendes verwenden:
public static string TrimStart(this string target, string trimChars)
{
return target.TrimStart(trimChars.ToCharArray());
}
public static string TrimEnd(this string target, string trimChars)
{
return target.TrimEnd(trimChars.ToCharArray());
}
string.ToCharArray()Tipp.
TrimStart/End(trimChars.ToCharArray());wirklich gelöscht werden. Das wird so gut wie nie wie erwartet funktionieren, außer in einem naiven Test und dann in der Produktion.
trimString == ""auch nicht sicher sind, ob Sie es immer wollen "12123".TimeStart("12") == "3".
TrimStart und TrimEnd nehmen eine Reihe von Zeichen auf. Dies bedeutet, dass Sie eine Zeichenfolge wie folgt als char-Array übergeben können:
var trimChars = " .+-";
var trimmed = myString.TrimStart(trimChars.ToCharArray());
Daher sehe ich keine Notwendigkeit für eine Überladung, die einen Zeichenfolgenparameter benötigt.
myString="Sammy"und trimChars="Sam"es wird "y" zurückgeben, aber das erwartete Ergebnis ist "my". Es schneidet also zu viel und betrachtet das Trimmwort nicht als solches.
myString="Sammy"und haben trimChars="SaX"; Dies führt zu "mmy". Stellen Sie sicher, dass dies Ihr gewünschtes Verhalten ist
Ich dachte, die Frage würde versuchen, eine bestimmte Zeichenfolge vom Anfang einer größeren Zeichenfolge aus zu kürzen.
Wenn ich zum Beispiel die Zeichenfolge "hellohellogoodbyehello" hätte und Sie versuchen würden, TrimStart ("hallo") aufzurufen, würden Sie "goodbyehello" zurückbekommen.
In diesem Fall können Sie folgenden Code verwenden:
string TrimStart(string source, string toTrim)
{
string s = source;
while (s.StartsWith(toTrim))
{
s = s.Substring(toTrim.Length - 1);
}
return s;
}
Dies wäre nicht sehr effizient, wenn Sie viel Schnur schneiden müssten, aber wenn es nur für einige Fälle ist, ist es einfach und erledigt die Arbeit.
toTrim.lengthohne das -1Recht sein?
Um die gesamte Zeichenfolge abzugleichen und nicht mehrere Teilzeichenfolgen zuzuweisen, sollten Sie Folgendes verwenden:
public static string TrimStart(this string source, string value, StringComparison comparisonType)
{
if (source == null)
{
throw new ArgumentNullException(nameof(source));
}
int valueLength = value.Length;
int startIndex = 0;
while (source.IndexOf(value, startIndex, comparisonType) == startIndex)
{
startIndex += valueLength;
}
return source.Substring(startIndex);
}
public static string TrimEnd(this string source, string value, StringComparison comparisonType)
{
if (source == null)
{
throw new ArgumentNullException(nameof(source));
}
int sourceLength = source.Length;
int valueLength = value.Length;
int count = sourceLength;
while (source.LastIndexOf(value, count, comparisonType) == count - valueLength)
{
count -= valueLength;
}
return source.Substring(0, count);
}
if (source == null){return null;}in meiner App. Ich denke, es ist in diesen Fällen eine bessere Wahl.
von dotnetperls.com ,
Performance
Leider ist die TrimStart-Methode nicht stark optimiert. In bestimmten Situationen können Sie wahrscheinlich zeichenbasierten Iterationscode schreiben, der diese übertrifft. Dies liegt daran, dass ein Array erstellt werden muss, um TrimStart verwenden zu können.
Allerdings: Benutzerdefinierter Code würde nicht unbedingt ein Array erfordern. Für schnell entwickelte Anwendungen ist die TrimStart-Methode jedoch nützlich.
In C # ist keine Funktion integriert - Sie können jedoch eigene Erweiterungen schreiben, die sich genau so verhalten, wie Sie es erwarten.
Beachten Sie, dass Sie mit IndexOf / LastIndexOf auswählen können, ob zwischen Groß- und Kleinschreibung / Kultur unterschieden werden soll oder nicht.
Ich habe auch die Funktion "repetitive Trims" implementiert.
Es gibt eine Funktion TrimStr(..)Umgang mit beiden Ordnungen, plus drei Funktionen Implementierung .TrimStart(...), .TrimEnd(...)und .Trim(..)für die Kompatibilität mit den .NET - Ordnungen:
Probieren Sie es in DotNetFiddle aus
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);
}
Jetzt können Sie es einfach so verwenden
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());
das schafft die Ausgabe
Sam
Moin gibts Gips? gips gibts moin
gibts gips? gips gibts
Ich gehe davon aus, dass Sie damit meinen, dass Sie beispielsweise mit der Zeichenfolge "HelloWorld" und dem Aufruf der Funktion zum Trimmen des Starts mit "Hello" "World" erhalten würden. Ich würde argumentieren, dass dies wirklich eine Teilzeichenfolgenoperation ist, da Sie einen Teil der Zeichenfolge bekannter Länge entfernen, anstatt eine Trimmoperation, die eine unbekannte Zeichenfolgenlänge entfernt.
Aus diesem Grund haben wir einige Erweiterungsmethoden mit dem Namen SubstringAfterund erstellt SubstringBefore. Es wäre schön, sie im Framework zu haben, aber sie sind nicht so, dass Sie sie selbst implementieren müssen. Vergessen Sie nicht, einen StringComparisonParameter zu haben und Ordinalals Standard zu verwenden, wenn Sie ihn optional machen.
Wenn Sie eine möchten, die die integrierten Trimmfunktionen aus irgendeinem Grund nicht verwendet, vorausgesetzt, Sie möchten eine Eingabezeichenfolge zum Trimmen verwenden, z. B. "~!" im Wesentlichen das gleiche sein wie das in TrimStart eingebaute mit ['', '~', '!']
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;
}
Funktion zum Trimmen von Anfang / Ende eines Strings mit einem String-Parameter, jedoch nur einmal (keine Schleife, dieser Einzelfall ist beliebter, Schleife kann mit einem zusätzlichen Parameter hinzugefügt werden, um ihn auszulösen):
public static class BasicStringExtensions
{
public static string TrimStartString(this string str, string trimValue)
{
if (str.StartsWith(trimValue))
return str.TrimStart(trimValue.ToCharArray());
//otherwise don't modify
return str;
}
public static string TrimEndString(this string str, string trimValue)
{
if (str.EndsWith(trimValue))
return str.TrimEnd(trimValue.ToCharArray());
//otherwise don't modify
return str;
}
}
Wenn Sie den Ansatz "while-Schleife" implementieren möchten, müssen Sie, wie bereits erwähnt, nach leeren Zeichenfolgen suchen, da diese sonst für immer wiederholt werden können.