webentwicklung-frage-antwort-db.com.de

C # Regex.Split: Leere Ergebnisse entfernen

Ich arbeite an einer Anwendung, die Tausende von Zeilen importiert, wobei jede Zeile ein Format wie folgt hat:

|* 9070183020  |04.02.2011    |107222     |M/S SUNNY MEDICOS                  |GHAZIABAD                          |      32,768.00 |

Ich verwende die folgende Regex, um die Zeilen in die benötigten Daten aufzuteilen:

Regex lineSplitter = new Regex(@"(?:^\|\*|\|)\s*(.*?)\s+(?=\|)");
string[] columns = lineSplitter.Split(data);

foreach (string c in columns)
    Console.Write("[" + c + "] ");

Dies gibt mir folgendes Ergebnis:

[] [9070183020] [] [04.02.2011] [] [107222] [] [M/S SUNNY MEDICOS] [] [GHAZIABAD] [] [32,768.00] [|]

Nun habe ich zwei Fragen.
1. Wie entferne ich die leeren Ergebnisse? Ich weiß ich kann verwenden:

string[] columns = lineSplitter.Split(data).Where(s => !string.IsNullOrEmpty(s)).ToArray();

aber gibt es eine eingebaute Methode, um die leeren Ergebnisse zu entfernen?

2. Wie kann ich die letzte Leitung entfernen?

Danke für jede Hilfe .
Grüße,
Yogesh.

BEARBEITEN:
Ich glaube, meine Frage wurde ein wenig missverstanden. Es ging nie um wie ich es schaffen kann. Es ging nur um wie kann ich das tun, indem ich die Regex im obigen Code ändere.

Ich weiß, dass ich es auf viele Arten tun kann. Ich habe es bereits mit dem oben genannten Code mit einer Where-Klausel und mit einem alternativen Weg gemacht, der auch (mehr als zweimal) schneller ist:

Regex regex = new Regex(@"(^\|\*\s*)|(\s*\|\s*)");
data = regex.Replace(data, "|");

string[] columns = data.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);

Zweitens kann mein System als Testfall in der ursprünglichen Methode 92k + ​​solcher Zeilen in weniger als 1,5 Sekunden und in der zweiten Methode in weniger als 700 Millisekunden parsen, wobei ich in realen Fällen niemals mehr als ein paar tausend finden werde Ich denke nicht, dass ich über die Geschwindigkeit hier nachdenken muss. Meiner Meinung nach ist Geschwindigkeit in diesem Fall eine vorzeitige Optimierung.

Ich habe die Antwort auf meine erste Frage gefunden: Mit Split ist dies nicht möglich, da keine solche Option eingebaut ist.

Ich suche immer noch nach einer Antwort auf meine zweite Frage.

28
Yogesh
Regex lineSplitter = new Regex(@"[\s*\*]*\|[\s*\*]*");
var columns = lineSplitter.Split(data).Where(s => s != String.Empty);

oder Sie könnten einfach tun:

string[] columns = data.Split(new char[] {'|'}, StringSplitOptions.RemoveEmptyEntries);
foreach (string c in columns) this.textBox1.Text += "[" + c.Trim(' ', '*') + "] " + "\r\n";

Nein, es gibt keine Option zum Entfernen leerer Einträge für RegEx.Split wie für String.Split.

Sie können auch Übereinstimmungen verwenden.

40
Jaroslav Jandek

Ich denke, dass dies als Äquivalent dazu dienen kann, leere Zeichenfolgen zu entfernen:

string[] splitter = Regex.Split(textvalue,@"\s").Where(s => s != String.Empty).ToArray<string>();
2
Peter

Als Alternative zur Aufteilung, die immer dann zu Problemen führt, wenn Ihre Trennzeichen am Anfang und Ende der Eingabe vorhanden sind, können Sie versuchen, den Inhalt der Pipes abzugleichen:

foreach (var token in Regex.Matches(input, @"\|\*?\s*(\S[^|]*?)\s*(?=\|)"))
{
    Console.WriteLine("[{0}]", token.Groups[1].Value);
}

// Prints the following:
// [9070183020]
// [04.02.2011]
// [107222]
// [M/S SUNNY MEDICOS]
// [GHAZIABAD]
// [32,768.00]
1
Quick Joe Smith

Verwenden Sie in Ihrem Fall überhaupt keine Regex. Es scheint nicht, dass Sie eine Regex benötigen, und Regex ist viel langsamer (und hat einen viel höheren Aufwand) als direkt mit den Zeichenfolgenfunktionen.

Verwenden Sie also etwas wie:

const Char[] splitChars = new Char[] {'|'};

string[] splitData = data.Split(splitChars, StringSplitOptions.RemoveEmptyEntries)
1
Foxfire

Basierend auf der großartigen Antwort von @Jaroslav Jandek schrieb ich einen extension method, den ich hier stelle, vielleicht kann es Ihnen Zeit sparen.

/// <summary>
/// String.Split with RemoveEmptyEntries option for clean up empty entries from result
/// </summary>
/// <param name="s">Value to parse</param>
/// <param name="separator">The separator</param>
/// <param name="index">Hint: pass -1 to get Last item</param>
/// <param name="wholeResult">Get array of split value</param>
/// <returns></returns>
public static object CleanSplit(this string s, char separator, int index, bool wholeResult = false)
{
    if (string.IsNullOrWhiteSpace(s)) return "";

    var split = s.Split(new char[] { separator }, StringSplitOptions.RemoveEmptyEntries);

    if (wholeResult) return split;

    if (index == -1) return split.Last();

    if (split[index] != null) return split[index];

    return "";
}
0
Mehdi Dehghani

1. Wie entferne ich die leeren Ergebnisse?

Sie könnenLINQverwenden, um alle Einträge zu entfernen, die string entsprechen. Leere:

string[] columns = lineSplitter.Split(data); 
columns = columns.ToList().RemoveAll(c => c.Equals(string.Empty)).ToArray();

2. Wie kann ich die letzte Leitung entfernen?

Sie können LINQ hier verwenden, um alle Einträge zu entfernen, die dem Zeichen entsprechen, das Sie entfernen möchten:

columns = columns.ToList().RemoveAll(c => c.Equals("|")).ToArray();
0
CBinet

verwenden Sie diese Lösung:

string stringwithDelemeterNoEmptyValues= string.Join(",", stringwithDelemeterWithEmptyValues.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries));
0
Ghadir Farzaneh

Wie wäre es damit:

vorausgesetzt, wir haben eine Zeile:

line1="|* 9070183020  |04.02.2011    |107222     |M/S SUNNY MEDICOS                  |GHAZIABAD                          |      32,768.00 |";

wir können das gewünschte Ergebnis haben als:

string[] columns =Regex.Split(line1,"|");
foreach (string c in columns)
         c=c.Replace("*","").Trim();

Dies ergibt folgendes Ergebnis:

[9070183020] [04.02.2011] [107222] [M/S SUNNY MEDICOS] [GHAZIABAD] [32,768.00]
0
Ankush Roy

Ich habe hier vielleicht eine falsche Vorstellung, aber Sie möchten nur die Zeichenfolge data mit '|' aufteilen. Zeichen als Trennzeichen? In diesem Fall könnten Sie Folgendes versuchen:

string[] result = data.Split(new[] { "|" }, StringSplitOptions.RemoveEmptyEntries).Select(d => d.Trim()).ToArray();

Dadurch werden alle Felder ohne Leerzeichen und mit leeren Feldern zurückgegeben. Sie können, was Sie möchten, im Select-Teil die Ergebnisse formatieren, z.

.Select(d => "[" + d.Trim() + "]").ToArray();
0
Jason Evans