2015-10-23 5 views
6

I wie unten einen String haben, das Rohr getrennt ist, hat sie in doppelte Anführungszeichen Zeichenfolge (z. B.: „ANI“)Wie eine Zeichenfolge teilen mit als Rohr abgegrenzt (die nicht in doppelte Anführungszeichen ist

Wie ? ich spalten diese mit Rohrtrennzeichen (die nicht in doppelte Anführungszeichen sind)

511186|"ANI"|"ABCD-102091474|E|EFG"||"2013-07-20 13:47:19.556" 

Und gespaltet Werte shoule wie unten sein:

511186 
"ANI" 
"ABCD-102091474|E|EFG" 

"2013-07-20 13:47:19.556" 

Jede Hilfe würde geschätzt

EDIT

Die Antwort, die ich akzeptiert, nicht für die Saiten nicht funktioniert, die in doppelten Anführungszeichen hat. Irgendeine Idee, was sollte das Problem sein?

using System.Text.RegularExpressions; 
string regexFormat = string.Format(@"(?:^|\{0})(""[^""]*""|[^\{0}]*)", '|'); 
string[] result = Regex.Matches("111001103|\"E\"|\"BBB\"|\"XXX\"|||10000009|153086649|\"BCTV\"|\"REV\"|||1.00000000|||||\"ABC-BT AD\"|\"\"\"ABC - BT\"\" AD\"|||\"N\"||\"N\"|||\"N\"||\"N",regexFormat) 
    .Cast<Match>().Select(m => m.Groups[1].Value).ToArray(); 
    foreach(var i in result) 
    Console.WriteLine(i) 
+0

Tag Ihre Frage mit regex und ich bin sicher, dass jemand kommen wird und wahrscheinlich in der Lage, Ihnen einen zu geben, um die Schnur zu teilen, wie Sie wollen. –

+0

Danke, hat das gemacht. – Relativity

Antwort

1

Sie können einen regulären Ausdruck verwenden, um die Elemente in der Zeichenfolge entsprechen:

string[] result = Regex.Matches(s, @"(?:^|\|)(""[^""]*""|[^|]*)") 
    .Cast<Match>() 
    .Select(m => m.Groups[1].Value) 
    .ToArray(); 

Erläuterung:

(?:  A non-capturing group 
^|\|  Matches start of string or a pipe character 
)   End of group 
(  Capturing group 
"[^"]*" Zero or more non-quotes surrounded by quotes 
|   Or 
[^|]*  Zero or more non-pipes 
)   End of group 
+0

Wenn das Trennzeichen Komma war, kann ich das verwenden -> "(?: ^, \,) (" "[^" "] *" "| [^,] *)" – Relativity

+1

@Relativity: Nein, die erste Pipe ist der oder Operator, also solltest du das behalten, und du musst dem Komma nicht entkommen: '@" (?:^|,) ("" [^ ""] * "" | [^,] *) " '. – Guffa

+0

Wenn wir Komma entkommen, ist das gut? ... weil ich einen allgemeinen Ausdruck erstelle ... wo ich string.format verwenden kann, um es dynamisch zu machen. Zeichenfolge regexFormat = Zeichenfolge.Format (@ "(?:^| \ {0}) (" "[^" "] *" "| [^ {0}] *)", delim); – Relativity

0
string.Split("|", inputString); 

... Sie werden die einzelnen Teile geben, aber fehlschlagen, wenn eine der Teile in ihnen ein Rohrtrenner haben.

Wenn es sich um eine CSV-Datei handelt, die alle üblichen CSV-Regeln für die Zeichenumleitung usw. verwendet (aber statt eines Kommas ein Pipe-Symbol verwendet), sollten Sie CsvHelper verwenden, ein NuGet-Paket zum Lesen und Schreiben CSV-Dateien. Es macht all die harte Arbeit und kümmert sich um alle Fälle, die Sie sonst selbst tun müssten.

+0

Hoppla! Ich habe nicht bemerkt, dass Ihre Beispieleingabe in einigen Teilen bereits Rohrsymbole hatte, sorry. Sieh dir trotzdem CsvHelper an. –

1

Dies ist eine Möglichkeit, es zu tun:

public List<string> Parse(string str) 
{ 
    var parts = str.Split(new[] {"|"}, StringSplitOptions.None); 

    List<string> result = new List<string>(); 

    for (int i = 0; i < parts.Length; i++) 
    { 
     string part = parts[i]; 

     if (IsPartStart(part)) 
     { 
      List<string> sub_parts = new List<string>(); 

      do 
      { 
       sub_parts.Add(part); 
       i++; 
       part = parts[i]; 
      } while (!IsPartEnd(part)); 

      sub_parts.Add(part); 

      part = string.Join("|", sub_parts); 
     } 

     result.Add(part); 
    } 

    return result; 

} 

private bool IsPartStart(string part) 
{ 
    return (part.StartsWith("\"") && !part.EndsWith("\"")) ; 
} 

private bool IsPartEnd(string part) 
{ 
    return (!part.StartsWith("\"") && part.EndsWith("\"")); 
} 

Dies funktioniert, indem alles Aufspalten und es schließt sich dann einige der Teile, die bei der Suche nach Teilen muss verbinden, die mit " beginnt und entsprechende Teile, die mit Enden ".

0

So würde ich es machen. Es ist ziemlich einfach und ich denke, Sie werden feststellen, dass es auch sehr schnell ist. Ich habe keine Tests durchgeführt, aber ich bin ziemlich zuversichtlich, dass es schneller ist als reguläre Ausdrücke.

IEnumerable<string> Parse(string s) 
{ 
    int pos = 0; 

    while (pos < s.Length) 
    { 
     char endChar = '|'; 

     // Test for quoted value 
     if (s[pos] == '"') 
     { 
      pos++; 
      endChar = '"'; 
     } 

     // Extract this value 
     int newPos = s.IndexOf(endChar, pos); 
     if (newPos < 0) 
      newPos = s.Length; 
     yield return s.Substring(pos, newPos - pos); 

     // Move to start of next value 
     pos = newPos + 1; 
     if (pos < s.Length && s[pos] == '|') 
      pos++; 
    } 
} 
Verwandte Themen