2015-10-23 2 views
6

У меня есть строка, как показано ниже, которая отделена труба имеет двойные кавычки строки (например:. «АНИ»)Как разбить строку с разделителями в виде трубы (который не в двойных кавычках

Как ? Должен ли я разделить это с разделителем труб (которые не являются в двойных кавычках)

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

И расщепленные значения Shoule быть, как показано ниже:

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

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

Любая помощь будет оценена

EDIT

Ответ, который я принял, не работаю для тех строк, которые имеют двойные кавычки внутри. Любая идея, в чем проблема?

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

Тэг ваш вопрос с регулярным выражением, и я уверен, что кто-то придет и вероятно, сможет дать вам возможность разделить строку так, как вы хотите. –

+0

Спасибо, сделал это. – Relativity

ответ

1

Вы можете использовать регулярное выражение для соответствия элементов в строке:

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

Объяснение:

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

Если разделитель был запятой, могу ли я использовать это -> "(?: ^, \,) (" "[^" "] *" "| [^,] *)" – Relativity

+1

@ Релятивность: Нет, первая труба это оператор или, поэтому вы должны сохранить это, и вам не нужно скрывать запятую: '@" (?:^|,) ("" [^ ""] * "" | [^,] *) " '. – Guffa

+0

Если мы избежим запятой, это прекрасно? ... потому что я строю общее выражение ... где я cna использую string.format, чтобы сделать его динамичным. string regexFormat = string.Format (@ "(?:^| \ {0}) (" "[^" "] *" "| [^ {0}] *)", delim); – Relativity

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

... даст вам отдельные части, но потерпит неудачу, если какой-либо из частей имеют сепаратор труб в них.

Если это CSV-файл, следуя всем обычным правилам CSV об экранировании символов и т. Д. (Но используя символ трубы вместо запятой), вы должны посмотреть на использование CsvHelper, пакета NuGet, предназначенного для чтения и записи CSV-файлы. Он выполняет всю тяжелую работу и занимается всеми делами, которые вам приходилось делать самому.

+0

Упс! Я не заметил, что ваш пример ввода уже имел символы трубы в некоторых частях, извините. Тем не менее, проверьте CsvHelper. –

1

Вот один из способов сделать это:

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

Это работает, разделив все, и затем присоединяется некоторые из частей, которые нуждаются в объединении путем поиска частей, которые начинаются с " и соответствующими частями, которая заканчивается ".

0

Вот как я это сделаю. Это довольно просто, и я думаю, вы обнаружите, что это очень быстро. У меня не было никаких тестов, но я уверен, что это быстрее, чем регулярные выражения.

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++; 
    } 
} 
Смежные вопросы