2017-07-18 70 views
0

比较快的方式我有一个这样的(吨)string(S):来分割字符串

HKR,Drivers,SubClasses,,"wave,midi,mixer,aux"

基本上,我希望它在,字符分割成多个strings

但是,如果,字符在"之内或%之内,则应该忽略它。

在从线换句话说上述我期望的字符串:

HKR 
Drivers 
SubClasses 

"wave,midi,mixer,aux" 

(与由上面的空行中表示的一个空字符串)。

如果行是HKR,Drivers,SubClasses,,%wave,midi,mixer,aux%那么基本上与上面相同,当然只有返回的最后一个字符串应该是%wave,midi,mixer,aux%

我有一些工作代码,但它是令人难以置信的缓慢处理所有的线,我非常需要找到一个更快的方式来做到这一点。

private static IEnumerable<string> GetValues(string line) 
{ 
    var insideQuotes = false; 
    var insidePercent = false; 
    var startValueIndex = 0; 

    for (var i = 0; i < line.Length; i++) 
    { 
     if (line[i] == '%' && !insideQuotes) 
     { 
      insidePercent = !insidePercent; 
     } 

     if (line[i] == '"') 
     { 
      insideQuotes = !insideQuotes; 
     } 

     if (line[i] != ',' || insideQuotes || insidePercent) 
     { 
      continue; 
     } 

     yield return line.Substring(startValueIndex, i - startValueIndex); 
     startValueIndex = i + 1; 
    } 
} 

任何帮助,将不胜感激。

+0

如果你看过这个问题,我不想把它分成* every *','。 – cogumel0

+4

使用'VisualBasic.TextFieldParser'并设置['HasFieldsEnclosedInQuotes'](https://msdn.microsoft.com/en-us/library/microsoft.visualbasic.fileio.textfieldparser.hasfieldsenclosedinquotes(v = vs.110).aspx)到'真'。 –

+0

@ cogumel0他说的是在拆分中使用Regex – Yahya

回答

1

使用VisualBasic.TextFieldParser并将HasFieldsEnclosedInQuotes设置为true

我会使用的方法类似这样它处理一次所有行:

public static IEnumerable<string[]> GetValues(string allLines) 
{ 
    using (var parser = new Microsoft.VisualBasic.FileIO.TextFieldParser(new StringReader(allLines))) 
    { 
     parser.HasFieldsEnclosedInQuotes = true; 
     parser.Delimiters = new[] { "," }; 
     while (!parser.EndOfData) 
     { 
      string[] nextLineFields = parser.ReadFields(); 
      yield return nextLineFields; 
     } 
    } 
} 

你的样品:

var allLinesFields = GetValues("HKR,Drivers,SubClasses,,\"wave, midi, mixer, aux\""); 
foreach (string[] lineFields in allLinesFields) 
    Console.WriteLine(string.Join(Environment.NewLine, lineFields)); 

它将比String.Split更有效率,同时还支持其他的事情,你可能甚至没有想到。如果格式无效,您还可以处理特殊例外情况。

+1

不知道这将处理'%'中包含的字段,尽管 – Jamiec

+2

这个问题声称显示的代码太慢。这个答案没有证据表明这种方法更快。 – CodeCaster

+0

@Jamiec:这将是一个问题,还没有看到它:)所以OP不知道他的csv格式是什么格式?但是,他可以使用其他csv解析器,如支持它的[this](http://www.codeproject.com/Articles/9258/A-Fast-CSV-Reader) –

0

我刚刚重新排序了一些查询语句以避免字符串操作。这应该更有效率。

private static IEnumerable<string> GetValues2(string line) 
    { 
     bool insideQuotes = false; 
     bool insidePercent = false; 
     int startValueIndex = 0; 

     for (int i = 0; i < line.Length; i++) 
     { 
      if (!insideQuotes && line[i] == '%') 
      { 
       insidePercent = !insidePercent; 
      } 

      if (line[i] == '"') 
      { 
       insideQuotes = !insideQuotes; 
      } 

      if (insideQuotes || insidePercent || line[i] != ',') 
      { 
       continue; 
      } 

      yield return line.Substring(startValueIndex, i - startValueIndex); 
      startValueIndex = i + 1; 
     } 
    }