2015-10-23 8 views
6

Ho una stringa come qui di seguito, che è separata tubo Ha doppi apici stringa (es:. "ANI")Come dividere una stringa con delimitato come il tubo (che non è dentro le virgolette doppie

Come ? faccio a dividere questo con delimitatore tubo (che non sono all'interno di doppi apici)

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

E spacco valori shoule essere come di seguito:!

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

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

Qualsiasi aiuto sarebbe apprezzato

EDIT

La risposta che ho accettato, non ha funzionato per quelle corde che ha virgolette doppie all'interno. Qualche idea, quale dovrebbe essere il problema?

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 tua domanda con regex e sono sicuro che qualcuno entrerà e probabilmente sarà in grado di dartene uno per dividere la stringa nel modo desiderato. –

+0

Grazie, l'ho fatto. – Relativity

risposta

1

È possibile utilizzare un'espressione regolare per abbinare gli elementi nella stringa:

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

Spiegazione:

(?:  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

Se il delimitatore era virgola, posso usare questo -> "(?: ^, \,) (" "[^" "] *" "| [^,] *)" – Relativity

+1

@Relativity: No, la prima pipe è l'operatore o, quindi è necessario mantenerlo e non è necessario sfuggire alla virgola: '@" (?:^|,) ("" [^ ""] * "" | [^,] *) " '. – Guffa

+0

Se scappiamo dalla virgola, va bene? ... perché sto costruendo un'espressione comune ... dove posso usare string.format per renderlo dinamico. string regexFormat = string.Format (@ "(?:^| \ {0}) (" "[^" "] *" "| [^ {0}] *)", delim); – Relativity

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

... vi darà le singole parti, ma non riuscirà se una delle parti hanno un separatore pipe in loro.

Se si tratta di un file CSV, seguendo tutte le normali regole CSV sull'esclusione dei caratteri, ecc. File CSV. Fa tutto il duro lavoro e si occupa di tutti i casi d'angolo che altrimenti dovresti fare da solo.

+0

Oops! Non ho notato che il tuo input di esempio aveva già simboli di pipe in alcune parti, mi dispiace. Ancora, controlla CsvHelper. –

1

Ecco un modo per farlo:

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("\"")); 
} 

Questo funziona dividendo tutto, e si unisce poi alcune delle parti che ha bisogno di unione attraverso la ricerca di pezzi che inizia con " e corrispondenti parti che termina con ".

0

Ecco come lo farei. È abbastanza semplice e penso che troverai anche molto veloce. Non ho eseguito alcun test, ma sono abbastanza sicuro che sia più veloce delle espressioni regolari.

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++; 
    } 
} 
Problemi correlati