Benutzer mit den meisten Antworten
Anzahl der Vorkommen von String1 in String2 überprüfen, leerzeichen ignorieren

Frage
-
Ich muss in einem string die anzahl der Vorkommen von string2 zählen oder ersetzen. Ich dachte da an Regex.Matches bzw. Regex.Replace, aber dann fiel mir ein das ich ja auchoch die Leerzeichen ignorieren muss, also:
string input = "abc def gab cde fga bcd efg"; string pattern = "abc"; int x = SucheVorkommenVon(input, pattern); //x sollte jetzt 3 sein
string s = Ersetze(input, pattern, "123");
//s sollte jetzt "123 def g123de fg123d efg" sein
Gibt es da eine möglichkeit, oder müsste ich soas selbst schreiben?
Koopakiller - http://koopakiller.ko.ohost.de/
- Bearbeitet Tom Lambert (Koopakiller)Moderator Mittwoch, 22. Februar 2012 18:31
Antworten
-
Als regulären Ausdruck kannst du @"a\s*b\s*c" wählen:
string input = "abc def gab cde fga bcd efg"; string pattern = @"a\s*b\s*c"; Console.WriteLine(Regex.Matches(input, pattern).Count);
MVP Data Platform Development My blog
- Als Antwort markiert Tom Lambert (Koopakiller)Moderator Donnerstag, 23. Februar 2012 15:23
-
Mein Problem liegt leider darin das input ein x-beliebiger Text sein kann.
Den input kannst du doch einfach als erstes Argument an die Matches-Methode übergeben, da sehe ich nicht das Problem.
Wenn du als pattern die Zeichenkette "abc" erhälst, aber dabei Leerzeichen zwischen (und auch vor?) den Zeichen erlauben willst, dann muss man das Pattern erst erstellen, etwa per
string input = "abc def gab cde fga bcd efg"; string inputPattern = "abc"; StringBuilder sb = new StringBuilder(); sb.Append(@"\s*"); foreach (char c in inputPattern) { sb.Append(c); sb.Append(@"\s*"); } string pattern = sb.ToString(); Console.WriteLine(Regex.Matches(input, pattern).Count);
Ansonsten musst du detailierter erklären, wie die Zeichenketten aussehen können, die du erhälst, und was genau geprüft werden soll.
MVP Data Platform Development My blog
- Als Antwort markiert Tom Lambert (Koopakiller)Moderator Donnerstag, 23. Februar 2012 15:23
-
Hallo K.,
das sollte eigentlich mit der Replace-Methode von String oder StringBuilder machbar sein:
const string input = "abc def gab cde fga bcd efg"; const string searchPattern = "abc"; const string replacePattern = "123"; StringBuilder replaced = new StringBuilder(input); replaced.Replace(" ", String.Empty); // Leerzeichen entfernen replaced.Replace(searchPattern, replacePattern); string resultStr = replaced.ToString();
Falls du die Leerzeichen wieder an den alten Positionen eingefügt haben willst, musst du nur die Positionen vorher merken und danach wieder einfügen:
const string input = "abc def gab cde fga bcd efg"; const string searchPattern = "abc"; const string replacePattern = "123"; string[] words = input.Split(' '); // Positionen merken StringBuilder replaced = new StringBuilder(input); replaced.Replace(" ", String.Empty); replaced.Replace(searchPattern, replacePattern); // gemerkte Leerzeichen wieder einfügen int startPos = 0; foreach (string s in words) { replaced.Insert(startPos + s.Length, ' '); startPos += s.Length + 1; } string resultStr = replaced.ToString();
Dies funktioniert jedoch nur korrekt, wenn der zu ersetzende String gleich lang wie der ersetzte ist.
Ausserdem stimmt das Ergebnis zwar mit deiner Anforderungsbeschreibung, jedoch nicht mit deinem gewünschten Ergebnis überein, da du in deinem Beispielergebnis auch Leerzeichen die innerhalb des gefundenen Patterns sind, entfernt hast.
- Als Antwort markiert Tom Lambert (Koopakiller)Moderator Donnerstag, 23. Februar 2012 15:23
-
Danke für die Hilfe :)Ich habe mal 2 Funktionen geschrieben die genau das macen was ich will:
private int Matches(string input, string pattern, bool IgnoreCase) { return Regex.Matches(input.Replace(" ", ""), pattern.Replace(" ", ""), IgnoreCase ? RegexOptions.IgnoreCase : RegexOptions.None).Count; } private string Replace(string input, string pattern, string replace, bool IgnoreCase) { StringBuilder sb = new StringBuilder(); foreach (char c in pattern.Replace(" ", "")) { sb.Append(c); sb.Append(@"\s*"); } return Regex.Replace(input, sb.ToString().Substring(0, sb.ToString().Length - 3), replace, IgnoreCase ? RegexOptions.IgnoreCase : RegexOptions.None); }
Das IgnoreCase bezieht sich darauf noch die Groß-/Kleinschreibung zu ignorieren/ zu beachten.Koopakiller - http://koopakiller.ko.ohost.de/
- Als Antwort markiert Tom Lambert (Koopakiller)Moderator Donnerstag, 23. Februar 2012 15:23
Alle Antworten
-
Als regulären Ausdruck kannst du @"a\s*b\s*c" wählen:
string input = "abc def gab cde fga bcd efg"; string pattern = @"a\s*b\s*c"; Console.WriteLine(Regex.Matches(input, pattern).Count);
MVP Data Platform Development My blog
- Als Antwort markiert Tom Lambert (Koopakiller)Moderator Donnerstag, 23. Februar 2012 15:23
-
Hallo K.,
Martins Ansatz ist m.E. eher unabhängig von der Eingabe. Solange Du weißt wonach Du suchst und das Pattern entsprechend anpaßt, werden die Treffer nicht ausbleiben.
Aber vielleicht erklärst Du auch mal etwas detaillierter was Du eigtl. meinst (ein echtes Beispiel wäre auch nicht verkehrt).Gruß
Marcel -
Mein Problem liegt leider darin das input ein x-beliebiger Text sein kann.
Den input kannst du doch einfach als erstes Argument an die Matches-Methode übergeben, da sehe ich nicht das Problem.
Wenn du als pattern die Zeichenkette "abc" erhälst, aber dabei Leerzeichen zwischen (und auch vor?) den Zeichen erlauben willst, dann muss man das Pattern erst erstellen, etwa per
string input = "abc def gab cde fga bcd efg"; string inputPattern = "abc"; StringBuilder sb = new StringBuilder(); sb.Append(@"\s*"); foreach (char c in inputPattern) { sb.Append(c); sb.Append(@"\s*"); } string pattern = sb.ToString(); Console.WriteLine(Regex.Matches(input, pattern).Count);
Ansonsten musst du detailierter erklären, wie die Zeichenketten aussehen können, die du erhälst, und was genau geprüft werden soll.
MVP Data Platform Development My blog
- Als Antwort markiert Tom Lambert (Koopakiller)Moderator Donnerstag, 23. Februar 2012 15:23
-
Hallo K.,
das sollte eigentlich mit der Replace-Methode von String oder StringBuilder machbar sein:
const string input = "abc def gab cde fga bcd efg"; const string searchPattern = "abc"; const string replacePattern = "123"; StringBuilder replaced = new StringBuilder(input); replaced.Replace(" ", String.Empty); // Leerzeichen entfernen replaced.Replace(searchPattern, replacePattern); string resultStr = replaced.ToString();
Falls du die Leerzeichen wieder an den alten Positionen eingefügt haben willst, musst du nur die Positionen vorher merken und danach wieder einfügen:
const string input = "abc def gab cde fga bcd efg"; const string searchPattern = "abc"; const string replacePattern = "123"; string[] words = input.Split(' '); // Positionen merken StringBuilder replaced = new StringBuilder(input); replaced.Replace(" ", String.Empty); replaced.Replace(searchPattern, replacePattern); // gemerkte Leerzeichen wieder einfügen int startPos = 0; foreach (string s in words) { replaced.Insert(startPos + s.Length, ' '); startPos += s.Length + 1; } string resultStr = replaced.ToString();
Dies funktioniert jedoch nur korrekt, wenn der zu ersetzende String gleich lang wie der ersetzte ist.
Ausserdem stimmt das Ergebnis zwar mit deiner Anforderungsbeschreibung, jedoch nicht mit deinem gewünschten Ergebnis überein, da du in deinem Beispielergebnis auch Leerzeichen die innerhalb des gefundenen Patterns sind, entfernt hast.
- Als Antwort markiert Tom Lambert (Koopakiller)Moderator Donnerstag, 23. Februar 2012 15:23
-
Danke für die Hilfe :)Ich habe mal 2 Funktionen geschrieben die genau das macen was ich will:
private int Matches(string input, string pattern, bool IgnoreCase) { return Regex.Matches(input.Replace(" ", ""), pattern.Replace(" ", ""), IgnoreCase ? RegexOptions.IgnoreCase : RegexOptions.None).Count; } private string Replace(string input, string pattern, string replace, bool IgnoreCase) { StringBuilder sb = new StringBuilder(); foreach (char c in pattern.Replace(" ", "")) { sb.Append(c); sb.Append(@"\s*"); } return Regex.Replace(input, sb.ToString().Substring(0, sb.ToString().Length - 3), replace, IgnoreCase ? RegexOptions.IgnoreCase : RegexOptions.None); }
Das IgnoreCase bezieht sich darauf noch die Groß-/Kleinschreibung zu ignorieren/ zu beachten.Koopakiller - http://koopakiller.ko.ohost.de/
- Als Antwort markiert Tom Lambert (Koopakiller)Moderator Donnerstag, 23. Februar 2012 15:23