我不敢相信我在以下字符串上遇到了问题
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];
}
}