Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 解析逗号分隔的键值对_C#_Wcf_Parsing_Deserialization - Fatal编程技术网

C# 解析逗号分隔的键值对

C# 解析逗号分隔的键值对,c#,wcf,parsing,deserialization,C#,Wcf,Parsing,Deserialization,我有一个HTTP请求(授权)标头中的数据,该标头类似于以下内容: name="Dave O'Connel", "e-mail"="dave@mailinator.com", epoch=1498158305, "other value"="some arbitrary\" text, with comma = and equals symbol" 我想把它做成一对钥匙 由于以下原因,很难解析此数据: 键和值仅在包含非字母数字字符时才被引用 键和值可以包含逗号、(转义)双引号和等于符号 我有

我有一个HTTP请求(授权)标头中的数据,该标头类似于以下内容:

name="Dave O'Connel", "e-mail"="dave@mailinator.com", epoch=1498158305, "other value"="some arbitrary\" text, with comma = and equals symbol"
我想把它做成一对钥匙

由于以下原因,很难解析此数据:

  • 键和值仅在包含非字母数字字符时才被引用
  • 键和值可以包含逗号、(转义)双引号和等于符号

我有什么办法来处理这个问题?我尝试了CSV库,但结果不正确。

这段代码应该可以完成这项工作:

class Program
{
    static string Preprocess(string s)
    {
        bool esc = false, quoted = false;
        StringBuilder sb = new StringBuilder();
        foreach (var c in s)
        {
            if (c == '\\' && !esc)
                esc = true;
            else
            {
                if (c == '\"' && !esc)
                    quoted = !quoted;
                else
                {
                    if (c == '=' && quoted)
                        sb.Append('~');
                    else if (c == ',' && quoted)
                        sb.Append(';');
                    else
                        sb.Append(c);
                }
                esc = false;
            }
        }
        return sb.ToString();
    }

    static string Postprocess(string s)
    {
        return s.Replace('~', '=').Replace(';', ',');
    }

    static Dictionary<string, string> MakeKeyValueList(string str)
    {
        var dict = new Dictionary<string, string>();
        foreach (var kvp in Preprocess(str).Split(','))
        {
            string[] kv = kvp.Split(new char[] { '=' }, 2);
            if (kv.Length == 2)
                dict[Postprocess(kv[0]).Trim()] = Postprocess(kv[1]).Trim();
        }
        return dict;
    }

    static void Main(string[] args)
    {
        var dict = MakeKeyValueList("name=\"Dave O'Connel\", \"e-mail\"=\"dave@mailinator.com\", epoch=1498158305, \"other value\"=\"some arbitrary\\\" text, with comma = and equals symbol\"");
        foreach (var kvp in dict)
            Console.WriteLine(kvp.ToString());
        Console.ReadKey();
    }
}
类程序
{
静态字符串预处理(字符串s)
{
bool-esc=false,引号=false;
StringBuilder sb=新的StringBuilder();
foreach(s中的变量c)
{
如果(c=='\\'&&&!esc)
esc=真;
其他的
{
如果(c=='\'&&!esc)
quoted=!quoted;
其他的
{
if(c=='='&"e)
某人附加(“~”);
else if(c==','&"e)
某人附加(“;”);
其他的
sb.附加(c);
}
esc=假;
}
}
使某人返回字符串();
}
静态字符串后处理(字符串s)
{
返回s.Replace(“~”,“=”).Replace(“;”,“,”);
}
静态字典makeyValueList(字符串str)
{
var dict=新字典();
foreach(预处理中的var kvp(str).Split(','))
{
字符串[]kv=kvp.Split(新字符[]{'='},2);
如果(千伏长度==2)
dict[Postprocess(kv[0]).Trim()]=后处理(kv[1]).Trim();
}
返回命令;
}
静态void Main(字符串[]参数)
{
var dict=MakeKeyValueList(“姓名=\“Dave O'Connel\”,\“电子邮件=”dave@mailinator.com\“,epoch=1498158305,\”其他值\“=”一些任意\\”文本,带逗号=和等于符号\”);
foreach(dict中的var kvp)
Console.WriteLine(kvp.ToString());
Console.ReadKey();
}
}

我听很多人说:如果你用正则表达式解决一个问题,你就有两个问题。哦,好吧。。。如果您不想编写自己的解析器。。。这个小怪物工作得很好:

   public class Program
    {
        static void Main(string[] args)
        {
            Regex regex = new Regex("^(?:(?:[, ]+)?(?\'q\'\")?(?\'key\'[^=\"]*?)(?:\\k\'q\'(?\'-q\'))?=(?\'q\'\")?(?\'value\'(?:[^\"]|(?<=\\\\)\")*)(?:\\k\'q\'(?\'-q\'))?)*(?(q)(?!))$", RegexOptions.Compiled);

            string s = "name=\"Dave O\'Connel\", \"e-mail\"=\"dave@mailinator.com\", epoch=1498158305, \"other value\"=\"some arbitrary\\\" text, with comma = and equals symbol\"";

            Match match = regex.Match(s);

            if (match.Success)
            {
                var keys = match.Groups["key"].Captures;
                var values = match.Groups["value"].Captures;

                for (int i = 0; i < keys.Count; i++)
                {
                    Console.WriteLine(keys[i] + " = " + values[i]);
                    // this prints:
                    // name = Dave O'Connel
                    // e-mail = dave@mailinator.com
                    // epoch = 1498158305,
                    // other value = some arbitrary\" text, with comma = and equals symbol
                }
            }

            Console.ReadLine();
        }
    }
公共类程序
{
静态void Main(字符串[]参数)
{

正则表达式正则表达式=新正则表达式(“^(?:(?:[,]+)?(?\'q\'”)(?\'key\'[^=\']*?)(?:\\k\'q\'(?\'-q\'))?=(?\'q\'”)(?\'value\'(?:[^\”)|(?您可以修改从中获取数据的服务器?如果是,最好的解决方案是规范化服务器的响应。@S.Petrosov它实际上已经规范化了。所有文本值都被引用,字段中的引号都被转义。带有特殊字符的键值也被引用。这非常感谢。我甚至不打算尝试去理解正则表达式的e!我你想我可以为你剖析它并解释各个部分。而且,我相信有更好正则表达式技能的人可以用更短的方式重写它。。。