2016-06-19 52 views
1

我正在其中用户输入的一些数据,例如节目:劈裂字符串数组

222,“测试”,2 + 2

我不得不分割这个字符串用“”字符到一个数组,所以之前我就是用这个方法:

string[] parameters = userInput.Split (','); 

但是,现在它来到我的脑海如果用户输入的是这样的:

345, “测试,,,,,, ,,,,, ,,,,”,89

逗号只允许在我的项目中引号字符。

将该字符串拆分为数组的最快方法是什么?

编辑: 它不是解析CSV文件

编辑2:

预期返回{ “345”, “\” 测试,,,,,, ,,,,,, ,,, \ “”, “89”} - 此数组

+1

这听起来有点像在C#解析CSV文件。有很多图书馆可以做得很好。 –

+1

使用'StringSplitOptions'作为[Split function](https://msdn.microsoft.com/en-us/library/tabh47cf(v = vs.110).aspx)的第二个参数。 –

+1

[使用分隔符分隔,除非分隔符被转义]可能的重复(http://stackoverflow.com/questions/4403194/split-using-delimiter-except-when-delimiter-is-escaped) – mariosangiorgio

回答

1

编辑2

假设要返回的参数恒定数目的在3个元素,则可能有兴趣在Regex.Split function

var parameters = Regex.Split(userInput, @"^(?<first>\d+), (?<second>\D+), (?<third>\d+)$", 
            RegexOptions.ExplicitCapture) 
          .Where(a=>a!=string.Empty) 
          .ToList(); 

上面的代码返回一个List<string>{345, "test ,,,,,, ,,,,, ,,,,", 89}

编辑3

如果你想返回一个数组,替换上面的代码:

string[] parameters = Regex.Split(userInput, @"^(?<first>\d+), (?<second>\D+), (?<third>\d+)$", 
            RegexOptions.ExplicitCapture) 
          .Where(a=>a!=string.Empty) 
          .ToArray(); 

谢谢Lasee V. Karlsen的宝贵评论。

+1

实际上预计会返回一个3元素数组{“345”,“test ,,,,,, ,,,,, ,,,,”,“89”}。这完全是关于在引号中省略逗号。 – 107MP

+1

那么....'.ToArray()'然后呢? –

+0

@ LasseV.Karlsen,这可能是一个选项;) –

0

我已经通过遍历字符串来实现类似这样的事情。你需要的是一个标志,表明你是否在引用字符串内。

如果不在引用字符串内并遇到逗号,则会将当前位置的所有内容剪切到结果列表的新条目中。

当您在引用字符串之外遇到引号时,请设置该标志。

设置标志时,忽略所有逗号。当您遇到另一个报价时,请重新设置标志。

这是粗略的算法。

也就是说,你可以看看Microsoft.VisualBasic.FileIo.TextFieldParser这个类,它可能已经做了你所需要的。别担心,你可以在C#中使用它,也尽管命名空间

1

OP加EDIT2后,我张贴此
会离开,作为和锻炼的OP

bool inQuote = false; 
bool inComma = true; 
List<string> words = new List<string>(); 
StringBuilder sb = new StringBuilder(); 
foreach (char c in input) 
{ 
    if(c == '"') 
    { 
     if(inQuote) 
     { 
     inComma = false; 
     if(!String.IsnullOrEmpty(sb.ToString()) 
     { 
      words.Add(sb.ToString().Trim; 
      sb.Clear(); 
     } 
     inQuote = !inQuote;    
     continue; 
     } 
    } 
    if (c == ',' && !inQuote) 
    { 
     if(inComma) 
     { 
     if(!String.IsnullOrEmpty(sb.ToString()) 
     { 
      words.Add(sb.ToString().Trim; 
      sb.Clear(); 
     } 
     inComma = !inComma; 
     continue; 
     } 
    } 
    sb.Add(c); 
} 
if(!String.IsnullOrEmpty(sb.ToString()) 
    words.Add(sb.ToString().Trim()); 
sb.Clear(); 
foreach (string s in words) 
{ 
    if(sb.Len > 0) 
     sb.Append(", "); 
    sb.Append(@"\"" + s + @"\""); // not sure if the is the correct syntax for " 
} 
Console.WriteLine(sb.ToString(); 

你需要处理与边缘情况下,像

,SDLF “aslkd”
,SDLF“aslkd,
什么关于C也不是开放的?

当你考虑所有的可能性时,这对于Split或Regex来说太过分了。

+0

我真的不明白你想要做什么。 – 107MP

+0

@ 107MP你是那个曾经的问题。你测试过了吗? – Paparazzi

0

如果顺序并不重要:

static void Main(string[] args) 
     { 
      string data = "345, \"test ,,,,,, ,,,,, ,,,,\", 89"; 

      string[] quoteValues = GetValueInQuote(data); 

      string[] result = data.Split(quoteValues, StringSplitOptions.RemoveEmptyEntries); 


      result = string.Join(string.Empty, result).Replace(" ", string.Empty).Split(new char[1]{','}, StringSplitOptions.RemoveEmptyEntries); 

      result = result.Concat(quoteValues).ToArray(); 

     } 

     static string[] GetValueInQuote(string data) 
     { 
      int quoteCount = data.Where(c => c == '\"').Count(); 



      if (quoteCount % 2 == 1) 
       throw new Exception("an odd number of quotes"); 


      string[] result = new string[quoteCount/2]; 



      for (int i = 0; i < result.Length; i++) 
      { 
       int first = data.IndexOf('\"'); 

       int second = data.IndexOf('\"', first + 1); 


       result[i] = data.Substring(first, second - first + 1); 
      } 

      return result; 

     }