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



我不敢相信我在以下字符串上遇到了问题

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

碰巧得到了我需要的模式,但是一旦我尝试拆分启动,我就会得到值为"模式=%%">

我能做什么?

忘了提此字符串中需要拆分的列表可能不按任何特定顺序排列。这是将从字符串集合中读取的字符串的单个示例(从属性.设置.过滤器读取这些过滤器(

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

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

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

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

foreach (string value in values)
{
    string[] pair = value.Split('=');
    string key = pair[0];
    string val = pair[1];
}
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];

这应该可以解决问题:

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"];

开始日期在数组中的节俭位置结束:

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
}

好吧,我尝试了这样的事情:

 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

这是你想要的吗?

看,现在的事情是你的Split第二次filter仍然从字符串的开头开始,并且它与;匹配,所以由于字符串没有改变,你仍然检索以前的匹配(所以你的索引访问器被 X 关闭(。

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

var keyValues = filter.Split(';');
var name = keyValues[0].Split('=')[1];
var pattern = keyValues[1].Split('=')[1];
var start = keyValues[2].Split('=')[1];
var end = keyValues[3].Split('=')[1];

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

您可以使用

以下内容:

 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);

使用这个:

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;
    }
}

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

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

我也

自己找到了一个简单的解决方案。如果列表每次都以相同的顺序排列,那么您的大多数答案都会起作用,但事实并非如此。但是,格式将始终保持不变。解决方案是使用 foreach 循环进行简单的迭代,然后检查它是否以某个单词开头,即我正在寻找的单词,如名称、模式等。

可能不是最高效的 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];
                    }
                }

最新更新