我在aspx页面上有一个从用户输入返回的字符串。 C#代码的第一块工作正常,我可以访问每个字典键值对。
string strsvresponse = "name:bob, age:22, city:Wolverhampton, state:West, Midlands, country:United Kingdom"
var dictusrdata = strsvresponse.Split(',')
.Select(x => x.Split(':'))
.ToDictionary(x => x[0], x => x[1]);
但是,微妙的区别是另一个用户决定在状态字段中添加一个逗号,该逗号引发错误“索引在数组的边界之外”。
string strsvresponse = "name:bob, age:22, city:Wolverhampton, state:West, Midlands, UK, country:United Kingdom"
var dictusrdata = strsvresponse.Split(',')
.Select(x => x.Split(':'))
.ToDictionary(x => x[0], x => x[1]);
我无法阻止用户这样做,但是我想知道是否有更好的方法来编码字符串以获取键值对或访问field:value数据?
谢谢 G
答案 0 :(得分:3)
首先:您的格式不明确。使用众所周知且广泛支持的格式:CSV,JSON,XML或更严格的格式。
如果您不能更改格式,则必须承担一些责任。假设标签是用逗号和空格分隔的单个单词:
var regex = "\\w+:.*?(?=(, \\w+:|$))";
string strsvresponse =
"name:bob, age:22, city:Wolverhampton, state:West, Midlands, UK, country:United Kingdom";
var dictusrdata = Regex.Matches(strsvresponse, regex)
.OfType<Match>()
.Select(a => a.Value.Split(':'))
.ToDictionary(a => a[0], a => a[1]);
正则表达式\w+:.*?(?=(, \w+:|$))
解释:
\w+ - any word
: - followed by : (this is TAG)
.*? - eat all chars lazily
(?= - lookahead assertion
(
, \w+: - make sure match is followed by [comma][space]TAG
| - or
$ - end of string
)
)
答案 1 :(得分:1)
这是一种实现方法:
string strsvresponse = "name:bob, age:22, city:Wolverhampton, state:West, Midlands, UK, country:United Kingdom";
var result = new Dictionary<String, String>();
var pairs = strsvresponse.Split(',');
for (int i = pairs.Count()-1; i >= 0; i--)
{
var pair = pairs[i].Split(':');
if (pair.Length == 2)
{
result.Add(pair[0].Trim(), pair[1].Trim());
}
else
{
pairs[i-1] = pairs[i-1] + pairs[i]; // add comma here if needed
}
}
return result;
这将为您提供这样的结果
请注意,state
吞下了多余的逗号。您可以根据需要将其重新添加-参见评论。同样,这假设逗号后但没有冒号的单词确实属于前一对。
我也同意其他评论者的意见,这是一种损坏的CSV格式,您需要从源头上解决问题-不允许进行此输入。但是解决这个小难题很有趣。
这是一个DotnetFiddle。
答案 2 :(得分:0)
您可以执行以下操作:
Dictionary<string, string> dic = new Dictionary<string, string>();
string strsvresponse = "name:bob, age:22, city:Wolverhampton, state:West Midlands, dfgdfgfdg,country: United Kingdom";
//First split by ','
var response = strsvresponse.Split(',');
foreach (var item in response)
{
//After splitting by ':' check if
//you have necessary values to create KeyValuePair
var dicVals = item.Split(':');
if(dicVals.Length != 2)
{
//TODO: Log error
continue;
}
dic.Add(dicVals[0], dicVals[1]);
}
答案 3 :(得分:0)
另一种方法是编写自定义解析器,这样您就可以编写自定义逻辑并控制数据处理。
string strsvresponse = "name:bob, age:22, city:Wolverhampton, state:West Midlands, UK, country: United Kingdom";
string iKey = string.Empty;
string iValue = string.Empty;
int iMode = 0;
Dictionary<string, string> dictusrdata = new Dictionary<string, string>();
for (int i = 0; i < strsvresponse.Length; i++)
{
if (iMode == 0)
{
if (strsvresponse[i] == ':')
{
iMode = 1;
}
else if (strsvresponse[i] == ',')
{
iKey = string.Empty;
iValue = string.Empty;
}
else
{
iKey += strsvresponse[i];
}
}
else
{
if (strsvresponse[i] == ',')
{
dictusrdata.Add(iKey.Trim(), iValue.Trim());
iKey = string.Empty;
iValue = string.Empty;
iMode = 0;
}
else
{
iValue += strsvresponse[i];
}
}
}
//add last value
if (!string.IsNullOrEmpty(iKey))
{
dictusrdata.Add(iKey.Trim(), iValue.Trim());
}