拆分包含多个符号的字符串以获取特定值

时间:2012-03-20 12:09:59

标签: c# split

我无法相信我遇到以下字符串

时出现问题
String filter = "name=Default;pattern=%%;start=Last;end=Now";

这是一个简短且可能重复的问题,但我如何将此字符串拆分为:

string Name = "Default";
string Pattern = "%%" ;
string start = "Last" ;
string end = "Now" ;

我问的原因是我的截止日期很快,这实际上是我必须做的最后一件事。我很恐慌,我坚持这个基本命令。我试过了:

pattern = filter.Split(new string[] { "pattern=", ";" },
                       StringSplitOptions.RemoveEmptyEntries)[1]; //Gets the pattern
startDate = filter.Split(new string[] { "start=", ";" },
                         StringSplitOptions.RemoveEmptyEntries)[1]; //Gets the start date

我碰巧得到了我需要的模式,但是当我尝试拆分开始时,我得到的值为“Pattern = %%”

我该怎么办?

忘记提及 此字符串中需要拆分的列表可能没有任何特定顺序。这是一个字符串的单个样本,它将从stringCollection中读出(从Properties.Settings.Filters中读取这些过滤器

9 个答案:

答案 0 :(得分:3)

使用string.Split这是一个两阶段的过程。

在第一种情况下,在;上拆分以获取一组关键字和值对:

string[] values = filter.Split(';');

然后遍历=上的结果列表拆分以获取关键字和值:

foreach (string value in values)
{
    string[] pair = value.Split('=');
    string key = pair[0];
    string val = pair[1];
}

答案 1 :(得分:2)

String filter = "name=Default;pattern=%%;start=Last;end=Now";
string[] temp = filter.Split('=');
string name = temp[1].Split(';')[0];
string pattern = temp[2].Split(';')[0];
string start = temp[3].Split(';')[0];
string end = temp[4].Split(';')[0];

答案 2 :(得分:2)

这应该可以解决问题:

string filter = "name=Default;pattern=%%;start=Last;end=Now";

// Make a dictionary.
var lookup = filter
   .Split(';')
   .Select(keyValuePair => keyValuePair.Split('='))
   .ToDictionary(parts => parts[0], parts => parts[1]);

// Get values out of the dictionary.
string name = lookup["name"];
string pattern = lookup["pattern"];
string start = lookup["start"];
string end = lookup["end"];

答案 3 :(得分:1)

开始日期最终在数组中的thrird位置:

startDate = filter.Split(new string[] { "start=", ";" }, StringSplitOptions.RemoveEmptyEntries)[2];

您可能希望将其拆分为单独的键值对,然后拆分每对值,而不是为每个值拆分字符串一次:

string[] pairs = filter.Split(';');
string[] values = pairs.Select(pair => pair.Split('=')[1]).ToArray();

string name = values[0];
string pattern = values[1];
string start = values[2];
string end = values[3];

(这段代码当然假设键值对总是以相同的顺序排列。)

您还可以将字符串拆分为交错数组,以便每个其他项都是键或值:

string[] values = filter.Split(new string[] { "=", ";" }, StringSplitOptions.None);

string name = values[1];
string pattern = values[3];
string start = values[5];
string end = values[7];

编辑:

要以任何顺序处理键值,请从字符串中进行查找,然后从中选择值:

ILookup<string, string> values =
  filter.Split(';')
  .Select(s => s.Split('='))
  .ToLookup(p => p[0], p => p[1]);

string name = values["name"].Single();
string pattern = values["pattern"].Single();
string start = values["start"].Single();
string end = values["end"].Single();

如果您想支持字符串中缺少的值,可以使用SingleOrDefault

string name = values["name"].SingleOrDefault() ?? "DefaultName";

查找还支持重复的键值对。如果可能存在重复项,只需遍历值:

foreach (var string name in values["name"]) {
  // do something with the name
}

答案 4 :(得分:1)

你知道,现在的事情是你的Split filter第二次仍然从字符串的开头开始,它与{{1}匹配因为字符串没有改变,你仍然可以检索以前的匹配(所以你的索引访问者被 X 关闭)。

您可以将其分解为问题部分,例如:

;

请注意,上述代码可能容易出错,因此应正确更改。

答案 5 :(得分:1)

我尝试过这样的事情:

 var result = "name=Default;pattern=%%;start=Last;end=Now".Split(new char[]{'=',';'});

  for(int i=0;i<result.Length; i++)
  {          
      if(i%2 == 0) continue;
      Console.WriteLine(result[i]);
  }

,输出为:

Default
%%
Last
Now

这是你想要的吗?

答案 6 :(得分:0)

您可以使用以下内容:

 String filter = "name=Default;pattern=%%;start=Last;end=Now";
 string[] parts = filter.Split(';');

 string Name = parts[0].Substring(parts[0].IndexOf('=') + 1);
 string Pattern = parts[1].Substring(parts[1].IndexOf('=') + 1);
 string start = parts[2].Substring(parts[2].IndexOf('=') + 1);
 string end = parts[3].Substring(parts[3].IndexOf('=') + 1);

答案 7 :(得分:0)

使用此:

String filter = "name=Default;pattern=%%;start=Last;end=Now";
var parts = filter.Split(';').Select(x => x.Split('='))
                             .Where(x => x.Length == 2)
                             .Select(x => new {key = x[0], value=x[1]});
string name = "";
string pattern = "";
string start = "";
string end = "";
foreach(var part in parts)
{
    switch(part.key)
    {
        case "name":
            name = part.value;
            break;
        case "pattern":
            pattern = part.value;
            break;
        case "start":
            start = part.value;
            break;
        case "end":
            end = part.value;
            break;
    }
}

如果您不需要命名变量中的值,则只需要第二行。它返回一个带有键/值对的枚举。

我的解决方案还有一个额外的好处,即字符串中这些键/值对的顺序是无关紧要的,它会默默地忽略无效部分而不是崩溃。

答案 8 :(得分:0)

我也找到了一个简单的解决方案。如果列表每次都以相同的顺序排列,那么你的大部分答案都会有效,但事实并非如此。然而,格式将始终保持不变。解决方案是使用foreach循环进行简单迭代,然后检查它是否以某个单词开头,即我要查找的单词,如Name,Pattern等。

可能不是最有效的cpu方式,但它是C#的傻瓜级别。真的是大脑褪色程度。

这是我的美丽。

                foreach (string subfilter in filter.Split(';')) //filter.Split is a string [] which can be iterated through
                {
                    if (subfilter.ToUpper().StartsWith("PATTERN"))
                    {
                        pattern = subfilter.Split('=')[1];
                    }
                    if (subfilter.ToUpper().StartsWith("START"))
                    {
                        startDate = subfilter.Split('=')[1];
                    }
                    if (subfilter.ToUpper().StartsWith("END"))
                    {
                        endDate = subfilter.Split('=')[1];
                    }
                }