将字符串拆分为数组

时间:2016-06-19 17:34:27

标签: c# arrays

我正在处理一个用户输入一些数据的程序,例如:

  

222," test",2 + 2

我必须将此字符串拆分为',' char进入一个数组,所以在我使用这个方法之前:

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

但是,现在我想到了如果用户输入这样的内容:

  

345," test ,,,,,, ,,,,, ,,,,",89

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

考虑到这个问题,将该字符串拆分成数组的最快方法是什么?

编辑: 它没有解析CSV文件

编辑2:

预计将返回{" 345"," \" test ,,,,,, ,,,,, ,,,, \"&# 34;," 89"} - 此数组中的3个元素

4 个答案:

答案 0 :(得分:1)

编辑2

假设您想要返回固定数量的参数,您可能会对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 :(得分:1)

OP发布此后添加了Edit2 将其留作OP并运用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而且都不开放?

当你考虑所有可能性时,这对于斯普利特或正则表达来说太过分了。

答案 2 :(得分:0)

我通过循环遍历字符串实现了类似的功能。你需要的是一个标志,指示你是否在引用的字符串中。

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

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

设置标志后,您将忽略所有逗号。当您遇到另一个引号时,请重置该标志。

这是粗略的算法。

那就是说,你可以看看Microsoft.VisualBasic.FileIo.TextFieldParser类,它可能已经做你需要的了。不用担心,尽管有命名空间

,你也可以在C#中使用它

答案 3 :(得分: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;

        }