【问题标题】:C# .net regex extracting a string from within a stringC# .net 正则表达式从字符串中提取字符串
【发布时间】:2017-03-14 19:10:47
【问题描述】:

我有一个如下所示的字符串输出:

ID       = GC5c.U.feab4bc5-8-92e-c486eaddddf8
AESKEY1  = efbf5c9db259e345c205b0da27f6fb459D
AESKEY2  = ea85af9f1e5f42ff4fe8b9f07e7dcebc68
DESKEY1  = 6388a9e1a2fc8981189f0f412ae4e8

ID       = JNPa.T.71664548-82-be2-a51aadd4a6f3
AESKEY1  = 37af9242c8879414e420f46903c16adebd3
AESKEY2  = 1259a1f6f6da03cb3984a117ca617d9ff73
DESKEY1  = 9547dc08db70cb95789f3a59e5c6adebd31

如何遍历该列表的 ID 并获取字符串中的值?

【问题讨论】:

    标签: c# .net regex string


    【解决方案1】:

    打开文件,遍历每一行,放入Dictionary<string, string>

    Dictionary<string, string> data = new Dictionary<string, string>();
    
    using(StreamReader reader = new StreamReader("C:/YourFilePath.txt"))
    {    
       while (reader.Peek() >= 0)
       {
            string[] line = reader.ReadLine().Split('=');
            data.Add(line[0].TrimEnd(), line[1].TrimStart());
       }
    }
    

    更新:请注意,此解决方案使用字典,因此它不允许重复键。如果您需要复制密钥,我建议将此解决方案更改为 List&lt;KeyValuePair&lt;string, string&gt;&gt;。顺便说一下,代码会有点脏:

    List<KeyValuePair<string, string>> data = new List<KeyValuePair<string, string>>();
    
    using(StreamReader reader = new StreamReader("C:/YourFilePath.txt"))
    {    
       while (reader.Peek() >= 0)
       {
            string[] line = reader.ReadLine().Split('=');
            data.Add(new KeyValuePair(line[0].TrimEnd(), line[1].TrimStart()));
       }
    }
    

    【讨论】:

      【解决方案2】:

      我不确定 Regex 是否最适合这种情况,但是,请在下面找到将其与命名组 "id" 一起使用的解决方案。

      var regex = new Regex(@"id.*=\s*(?<id>.+)", RegexOptions.IgnoreCase);
      var input = @"ID       = Gs3c.H.feab4bc5-6c00-4ee8-9e2e-c486eaddddf8
                    AESKEY1  = efbf5c9db259e345c205b0da27f6fb459D
                    AESKEY2  = ea85af9f1e5f42ff4fe8b9f07e7dcebc68
                    DESKEY1  = 6388a9e1a2fc8981189f0f412ae4e8
      
                    ID       = JNPa.T.71664548-82-be2-a51aadd4a6f3
                    AESKEY1  = 37af9242c8879414e420f46903c16adebd3
                    AESKEY2  = 1259a1f6f6da03cb3984a117ca617d9ff73
                    DESKEY1  = 9547dc08db70cb95789f3a59e5c6adebd31";
      
      var ids = regex.Matches(input).Cast<Match>().Select(m => m.Groups["id"]);
      

      这是正则表达式测试:Regex test

      【讨论】:

        【解决方案3】:

        NicoRiff 建议使用常规解析为Dictionary 是可行的方法。这是强制性的基于 LINQ 的方法:

        var data = File.ReadLines("C:/your/file/path.txt")
                       .Select(l => l.Split('='))
                       .ToDictionary(k => k[0], v => v[1]);
        

        编辑: 正如 Nico 指出的那样,当字典将包含重复键时,字典将不起作用。但是,您仍然可以使用 LINQ 自动排列字典,以便源文本的 ID 字段是键而不是字段名称。例如,您可以使用以下内容:

        var data = File.ReadLines("C:/your/file/path.txt")
                       .Where(l => !String.IsNullOrEmpty(l))
                       .Select((l, i) => new { ID = i / 4, Value = l.Split('=') })
                       .GroupBy(x => x.ID)
                       .Select(g => new { ID = g.First().Value[1].Trim(), Values = g.ToDictionary(k => k.Value[0].Trim(), v => v.Value[1].Trim()) })
                       .ToDictionary(k => k.ID, v => v.Values);
        

        之后,您可以遍历 data 以获取您的字段:

        foreach (var d in data.Values)
        {
            string id = d["ID"];
            string aesKey1 = d["AESKEY1"];
            string aesKey2 = d["AESKEY2"];
            string desKey1 = d["DESKEY1"];
        }
        

        【讨论】:

        • 起初,Dictionary 似乎是解决这个问题的方法。但似乎 OP 需要在字典中有重复的键,所以我认为这不起作用。我编辑了我的答案,以提供一个有用的解决方法。
        • @NicoRiff 我也在努力解决这个问题。
        【解决方案4】:

        如果您想将数据放入字典中,例如:Dicationary&lt;string, Dictionary&lt;string,string&gt;&gt;
        其中主字典的key是ID的值,而内部字典是后面的值,那么下面就可以了:

        string[] lines = input.Split('\n');
        var myDict = new Dictionary<string, Dictionary<string,string>>();
        var currentKey = "";
        
        foreach (string[] keyVal in lines.Where(line=>!string.IsNullOrWhiteSpace(line))
                                         .Select(line => line.Split('='))) 
        {
            if (keyVal[0].StartsWith("ID"))
            {
                currentKey = keyVal[1].Trim();
                myDict.Add(currentKey, new Dictionary<string, string>());
            }
            else
            {
                myDict[currentKey].Add(keyVal[0].Trim(), keyVal[1].Trim());
            }
        }
        

        【讨论】:

          【解决方案5】:

          正则表达式看起来像这样:

          @"^ID\s+=\s+(.+)$"
          

          您可以在Regex101Rextester 上进行测试

          【讨论】:

            猜你喜欢
            • 2014-08-25
            • 1970-01-01
            • 2014-10-17
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-10-14
            相关资源
            最近更新 更多