【问题标题】:Using c# to convert string to a dictionary使用c#将字符串转换为字典
【发布时间】:2019-07-05 08:49:43
【问题描述】:

我从日志服务获得以下字符串:

[("Browser": "Chrome73 (v 73.0)"), ("UserAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36"), ("Languages": ["nb-NO", "nb;q=0.9", "no;q=0.8", "nn;q=0.7", "en-US;q=0.6", "en;q=0.5"]), ("UserClaim-1-http://schemas.microsoft.com/ws/2008/06/identity/claims/role": "Admin"), ("SessionId": "hhaztuwfpyuobfslljuy4z4e"), ("Cookie-__RequestVerificationToken": "9MJm_A4agsgbe4c_JtAePFnfMLBEgnkc0XhROfDFVd6291SUGtLPAqprsGHBcJw9JDRde6UR_1jHY_Hr4oKi4OZzuUDXqAA6IfeEtr9sxVI1"), ("Cookie-.ASPXAUTH": "AA23B2B1A5C428BFB60E32EA5A78A7D5016D7586F88548C012A1C2C2EB2A34D40A959B43680BCCE9923F1890017F59A3A82E6C1121AF50CF226D638FBCBC40F2D8E2FE4C945B44CC7572717D56C71FCC0B7B285A0EB5379370ADC6BE970E6438"), ("Cookie-ASP.NET_SessionId": "hhaztuwfpyuobfslljuy4z4e"), ("Info-FamilyId": 21267), ("Info-LoggedInUserID": 1), ("Info-MainConsultantUserId": 3)]

我想把它变成一本字典。我认为我应该是一个简单的任务,但我一直在尝试以各种方式解析字符串但没有成功。谁能指出我正确的方向?

我一直在尝试使用:

var x = JsonConvert.DeserializeObject(the_string_above);

我得到了例外: 解析值时遇到意外字符。 (.Path '',第 1 行,位置 1)

如 cmets 中所指出的,格式不是有效的 JSON,所以问题是我如何解析文本...

【问题讨论】:

  • 不要自己解析 JSON,使用 JSON 解析器,例如牛顿软件。
  • 字典数组是什么意思?这看起来像一个键值元组数组,所以一个字典?
  • 您应该使用合适的反序列化器对其进行反序列化,而不是依靠经过测试和批准的功能自行完成。 stackoverflow.com/questions/7895105/…
  • 我认为我应该是一个简单的任务,但我一直在尝试以各种方式解析字符串但没有成功向我们展示你到目前为止得到的结果。
  • @Liknes 我已经为此尝试了正则表达式解决方案。请查看工作演示并让我知道它是否足够:dotnetfiddle.net/u1YbBK

标签: c# json dictionary


【解决方案1】:

所以我的尝试是基于 Regex 的解决方案,但 JSON 解决方案会更好、更高效。我已经为您的字符串准备了一个基于正则表达式的示例解决方案。

using System;
using System.Text.RegularExpressions;

public class Program
{
    public static void Main()
    {
         string str = "[(\"Browser\": \"Chrome73 (v 73.0)\"), (\"UserAgent\": \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36\"), (\"Languages\": [\"nb-NO\", \"nb;q=0.9\", \"no;q=0.8\", \"nn;q=0.7\", \"en-US;q=0.6\", \"en;q=0.5\"]), (\"UserClaim-1-http://schemas.microsoft.com/ws/2008/06/identity/claims/role\": \"Admin\"), (\"SessionId\": \"hhaztuwfpyuobfslljuy4z4e\"), (\"Cookie-__RequestVerificationToken\": \"9MJm_A4agsgbe4c_JtAePFnfMLBEgnkc0XhROfDFVd6291SUGtLPAqprsGHBcJw9JDRde6UR_1jHY_Hr4oKi4OZzuUDXqAA6IfeEtr9sxVI1\"), (\"Cookie-.ASPXAUTH\": \"AA23B2B1A5C428BFB60E32EA5A78A7D5016D7586F88548C012A1C2C2EB2A34D40A959B43680BCCE9923F1890017F59A3A82E6C1121AF50CF226D638FBCBC40F2D8E2FE4C945B44CC7572717D56C71FCC0B7B285A0EB5379370ADC6BE970E6438\"), (\"Cookie-ASP.NET_SessionId\": \"hhaztuwfpyuobfslljuy4z4e\"), (\"Info-FamilyId\": 21267), (\"Info-LoggedInUserID\": 1), (\"Info-MainConsultantUserId\": 3)]";
         showMatch(str, @"(?<=\()(.*?)(?=\)[,\]])");
    }

     private static void showMatch(string text, string expr) {
         MatchCollection mc = Regex.Matches(text, expr);

         foreach (Match m in mc) {
            Console.WriteLine(m);
         }
      }
}

这将输出:

"Browser": "Chrome73 (v 73.0)"
"UserAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36"
"Languages": ["nb-NO", "nb;q=0.9", "no;q=0.8", "nn;q=0.7", "en-US;q=0.6", "en;q=0.5"]
"UserClaim-1-http://schemas.microsoft.com/ws/2008/06/identity/claims/role": "Admin"
"SessionId": "hhaztuwfpyuobfslljuy4z4e"
"Cookie-__RequestVerificationToken": "9MJm_A4agsgbe4c_JtAePFnfMLBEgnkc0XhROfDFVd6291SUGtLPAqprsGHBcJw9JDRde6UR_1jHY_Hr4oKi4OZzuUDXqAA6IfeEtr9sxVI1"
"Cookie-.ASPXAUTH": "AA23B2B1A5C428BFB60E32EA5A78A7D5016D7586F88548C012A1C2C2EB2A34D40A959B43680BCCE9923F1890017F59A3A82E6C1121AF50CF226D638FBCBC40F2D8E2FE4C945B44CC7572717D56C71FCC0B7B285A0EB5379370ADC6BE970E6438"
"Cookie-ASP.NET_SessionId": "hhaztuwfpyuobfslljuy4z4e"
"Info-FamilyId": 21267
"Info-LoggedInUserID": 1
"Info-MainConsultantUserId": 3

工作演示:https://dotnetfiddle.net/u1YbBK

使用的正则表达式:(?&lt;=\()(.*?)(?=\)[,\]])

解释:

  1. Positive Lookbehind (?\( 与字符 ( 匹配(区分大小写)
  2. 第一个捕获组 (.*?):.*? 匹配任何字符(行终止符除外)和 *? 量词 - 匹配零次到无限次,尽可能少,根据需要扩展
  3. Positive Lookahead (?=)[,]]):\) 匹配字符 ) 字面意思(区分大小写)和 [,\]] , 匹配字符 , 字面意思(区分大小写)和 @ 987654335@ 与字符 ] 字面匹配(区分大小写)

【讨论】:

  • 谢谢!该解决方案的输出为我完成了它,据我所知,它对数据库中的所有记录数据都非常有效!我知道这个解决方案不是 100% 回答我的问题,而是帮助我解决了我的问题!
【解决方案2】:
[{"Browser": "Chrome73 {v 73.0}"}, {"UserAgent": "Mozilla/5.0 {Windows NT 10.0; Win64; x64} AppleWebKit/537.36 {KHTML, like Gecko} Chrome/73.0.3683.86 Safari/537.36"}, {"Languages": ["nb-NO", "nb;q=0.9", "no;q=0.8", "nn;q=0.7", "en-US;q=0.6", "en;q=0.5"]}, {"UserClaim-1-http://schemas.microsoft.com/ws/2008/06/identity/claims/role": "Admin"}, {"SessionId": "hhaztuwfpyuobfslljuy4z4e"}, {"Cookie-__RequestVerificationToken": "9MJm_A4agsgbe4c_JtAePFnfMLBEgnkc0XhROfDFVd6291SUGtLPAqprsGHBcJw9JDRde6UR_1jHY_Hr4oKi4OZzuUDXqAA6IfeEtr9sxVI1"}, {"Cookie-.ASPXAUTH": "AA23B2B1A5C428BFB60E32EA5A78A7D5016D7586F88548C012A1C2C2EB2A34D40A959B43680BCCE9923F1890017F59A3A82E6C1121AF50CF226D638FBCBC40F2D8E2FE4C945B44CC7572717D56C71FCC0B7B285A0EB5379370ADC6BE970E6438"}, {"Cookie-ASP.NET_SessionId": "hhaztuwfpyuobfslljuy4z4e"}, {"Info-FamilyId": 21267}, {"Info-LoggedInUserID": 1}, {"Info-MainConsultantUserId": 3}]

它可以找到,只需将 '(' 替换为 '{' & ')' 到 '}'

https://en.wikipedia.org/wiki/JSON 你可以看到 json 是如何工作的,也许你会丢失一些东西, 并使用http://json.parser.online.fr/ 尝试您的json 字符串。

【讨论】:

  • 谢谢!您的简单解决方案实际上适用于我在数据库中的所有数据,但它有点弄乱了数据。即 Chrome73 (v 73.0) 变成 Chrome73 {v 73.0}
【解决方案3】:

Rahul Sharma 的正则表达式转换示例:

using System;
using System.Text.RegularExpressions;
using System.Collections.Generic;

namespace Solution {

    public class Parser {

        public static Dictionary<string,string> parseLoggingInformation(string info) {

            Dictionary<string, string> ret = new Dictionary<string, string>();
            MatchCollection mc = Regex.Matches(info, @"(?<=\()(.*?)(?=\)[,\]])");
            foreach (Match m in mc) {
                string val = m.ToString();
                string[] vals;
                try {
                    vals = val.Split(new string[] { "\": \"" }, StringSplitOptions.None);
                    string tmp = vals[1];
                } catch (Exception) {
                    vals = val.Split(new string[] { "\": " }, StringSplitOptions.None);
                }
                string left = vals[0];
                string right = vals[1];
                ret.Add(left.Substring(1, left.Length - 1), right.Substring(0, right.Length - 1));
            }
            return ret;
        }

        public static void Main(String[] args) {
            GC.Collect();
            Dictionary<string, string> loggingData = parseLoggingInformation("[(\"Browser\": \"Chrome73 (v 73.0)\"), (\"UserAgent\": \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36\"), (\"Languages\": [\"nb-NO\", \"nb;q=0.9\", \"no;q=0.8\", \"nn;q=0.7\", \"en-US;q=0.6\", \"en;q=0.5\"]), (\"UserClaim-1-http://schemas.microsoft.com/ws/2008/06/identity/claims/role\": \"Admin\"), (\"SessionId\": \"hhaztuwfpyuobfslljuy4z4e\"), (\"Cookie-__RequestVerificationToken\": \"9MJm_A4agsgbe4c_JtAePFnfMLBEgnkc0XhROfDFVd6291SUGtLPAqprsGHBcJw9JDRde6UR_1jHY_Hr4oKi4OZzuUDXqAA6IfeEtr9sxVI1\"), (\"Cookie-.ASPXAUTH\": \"AA23B2B1A5C428BFB60E32EA5A78A7D5016D7586F88548C012A1C2C2EB2A34D40A959B43680BCCE9923F1890017F59A3A82E6C1121AF50CF226D638FBCBC40F2D8E2FE4C945B44CC7572717D56C71FCC0B7B285A0EB5379370ADC6BE970E6438\"), (\"Cookie-ASP.NET_SessionId\": \"hhaztuwfpyuobfslljuy4z4e\"), (\"Info-FamilyId\": 21267), (\"Info-LoggedInUserID\": 1), (\"Info-MainConsultantUserId\": 3)]");
        }
    }
}

它将收集到的数据保存在Dictionary&lt;string, string&gt;

【讨论】:

    【解决方案4】:

    好的,所以这个东西看起来几乎像一个 JSON 字典,只是

    1. 这是一个数组[],而不是一个字典{}。
    2. 键值元组括在() 中。

    所以最懒的想法就是把外面的括号改成{},这很琐碎,然后去掉不必要的()括号。您最终会得到一个有效的 JSON,可以直接使用 Newtonsoft.Json 或您选择的其他解析器进行解析。

    为了解析这个东西,我们将贪婪地转义引号中的所有() 括号并忽略所有其余部分。

    public static string LogToJson(string inputString)
    {
        var builder = new StringBuilder("{");
        var escaping = false;
    
        for (var index = 1 /* Skipping opening [ */ ; index < inputString.Length; ++index)
        {
            var @char = inputString[index];
            switch (@char)
            {
                case '(' when !escaping:
                case ')' when !escaping:
                    break;
                case '"':
                    escaping ^= true;
                    builder.Append(@char);
                    break;
                default:
                    builder.Append(@char);
                    break;
            }
        }
    
        builder.Length--; // Remove the final ]
        builder.Append("}");
        return builder.ToString();
    }
    

    请注意,这完全省略了错误处理并假定inputString 始终正确。因此,当且仅当在删除所有未转义的 () 括号后输入格式是正确的 json 时,它才能保证正确的 JSON。

    对于您的示例字符串,输出为:

    {"Browser": "Chrome73 (v 73.0)", "UserAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36", "Languages": ["nb-NO", "nb;q=0.9", "no;q=0.8", "nn;q=0.7", "en-US;q=0.6", "en;q=0.5"], "UserClaim-1-http://schemas.microsoft.com/ws/2008/06/identity/claims/role": "Admin", "SessionId": "hhaztuwfpyuobfslljuy4z4e", "Cookie-__RequestVerificationToken": "9MJm_A4agsgbe4c_JtAePFnfMLBEgnkc0XhROfDFVd6291SUGtLPAqprsGHBcJw9JDRde6UR_1jHY_Hr4oKi4OZzuUDXqAA6IfeEtr9sxVI1", "Cookie-.ASPXAUTH": "AA23B2B1A5C428BFB60E32EA5A78A7D5016D7586F88548C012A1C2C2EB2A34D40A959B43680BCCE9923F1890017F59A3A82E6C1121AF50CF226D638FBCBC40F2D8E2FE4C945B44CC7572717D56C71FCC0B7B285A0EB5379370ADC6BE970E6438", "Cookie-ASP.NET_SessionId": "hhaztuwfpyuobfslljuy4z4e", "Info-FamilyId": 21267, "Info-LoggedInUserID": 1, "Info-MainConsultantUserId": 3}
    

    【讨论】:

    • 这不是将字符串转换为字典,我认为这是 OP 所要求的。
    • 正如我所说,我们将字符串转换为 JSON,以便可以使用任何标准 JSON 解析器对其进行解析。那部分相当琐碎。
    猜你喜欢
    • 2014-09-02
    • 1970-01-01
    • 2012-09-07
    • 1970-01-01
    • 1970-01-01
    • 2021-07-25
    • 1970-01-01
    相关资源
    最近更新 更多