【问题标题】:Removing header from a formatted string从格式化的字符串中删除标题
【发布时间】:2019-01-09 18:19:20
【问题描述】:

我有一个正在尝试解析的格式化日志文件;该文件分为带有标题的部分,每个部分中的数据都使用 JSON 格式,如下所示。 Link to an extract of the log file here

[UnityCrossThreadLogger]1/8/2019 7:49:19 PM
==> Deck.GetDeckLists(112):
{

  "jsonrpc": "2.0",

  "method": "Deck.GetDeckLists",

  "params": {},

  "id": "112"

}

我的问题是以某种方式处理整个字符串,以到达我想要的部分,然后剥离无意义的数据并通过Newtonsoft JSON 解析剩余的数据。现在我正在使用此功能删除我不需要的所有内容,因为日志文件是按时间顺序排列的,并且只需要最近出现的条目:

//Cut the whole log to the last entry
    private static string CutLog(string fromWhereToCut)
    {
        string log = GetLog();
        //In this case fromWhereToCut would be "Deck.GetDeckLists"
        string s = log.Substring(log.LastIndexOf(fromWhereToCut));

        return s;
    }

问题在于,在反序列化 JSON 之前,我将标头保留在我需要删除的位置,并且 它很容易损坏,因为部分的名称不是那么独特 并且它们可以作为非标题标题进一步重复(如我的示例所示)。此外,在另一节开始之前,我不知道如何在我需要的部分结束时停下来。

我认为可以使用 RegEx,但即使对于 RegEx,这似乎也很大,也许有更好的解决方案。

【问题讨论】:

  • 是否有可能照顾'{'的第一次出现?
  • string s = log.Substring(log.LastIndexOf(fromWhereToCut) + fromWhereToCut.Length);?
  • @MikNiller 正如您在 Pastebin 中看到的(尤其是在最后一节中),它比这更复杂。
  • @AhmedAbdelhameed 这会给我留下可变数量的字符(括号“112”之间的部分),这些字符在日志文件的每次迭代中都会发生变化,这意味着一旦我可以获得 (112) 和另一个 ( 1).
  • 我明白了,那么另一个想法可能是寻找 [ 或 { ,当找到其中一个时,继续在字符串中搜索相同类型的匹配字符,然后将两者之间的数据提取为json,继续,直到字符串结束。可能效率不高,正则表达式大师很可能有更好的解决方案您需要通过保留某种引用计数来跟踪您正在搜索的块内的其他 { [

标签: c# regex string substring


【解决方案1】:

如果 Log 与 the one found in PasteBin 相同,则可以正常反序列化。
我正在使用支持类 (JSON_Logs) 来包含提取的数据。
在此模拟中,JSON 是从文件中读取的。

读取数据结构,识别实际数据开头的最可能候选者是重复出现的字符串"Deck.GetDeckLists"。在解析方法中,它被分配给一个名为 excludedSection 的变量。
数据在这些字符串的最后一个之后开始。我使用 logFile.LastIndexOf(excludedSection) 来查找这些条目中最后一个的索引,然后使用该索引来识别第一个数据结构。

JsonConvert.DeserializeObject 然后用于将数据反序列化为类对象列表。
我在反序列化过程中没有发现任何问题。

string searchString = "Deck.GetDeckLists";
List<JSON_Logs.Header> jsonLogs = ParseJsonLog(searchString, "JSON_Logs.txt");

private List<JSON_Logs.Header> ParseJsonLog(string excludedSection, string fileName)
{
    string logFile = File.ReadAllText(fileName);

    int refIndex = logFile.LastIndexOf(excludedSection);
    logFile = logFile.Substring(logFile.IndexOf("[", refIndex));

    return JsonConvert.DeserializeObject<List<JSON_Logs.Header>>(logFile);
}

支持类:

public class JSON_Logs
{
    public class Header
    {
        public string id { get; set; }
        public string name { get; set; }
        public string description { get; set; }
        public string format { get; set; }
        public string resourceId { get; set; }
        public int deckTileId { get; set; }
        public MainDeck[] mainDeck { get; set; }
        public object[] sideboard { get; set; }
        public DateTime lastUpdated { get; set; }
        public bool lockedForUse { get; set; }
        public bool lockedForEdit { get; set; }
        public bool isValid { get; set; }
    }

    public class MainDeck
    {
        public string id { get; set; }
        public int quantity { get; set; }
    }
}

【讨论】:

    【解决方案2】:

    我希望这是您所需要的。 :) 实际上,正则表达式在 all 部分中找到了 json,但我只包含了最后一部分 (matches[matches.Count - 1])。由于 JToken 没有 TryParse 方法,所以你必须使用 try/catch:

    static void ParseLog()
    {
        var s = File.ReadAllText(@"C:\log.json");
        var pattern =
            @"(?s)(?'header'\[\w+\]\d{1,2}/\d{1,2}/\d{4}\s\d{1,2}:\d{1,2}:\d{1,2}\s(A|P)M\r\n" +
            @"<?==>?.+?\r\n)" +
            @"(?'body'.+?)(?=$|\[\w+\]\d{1,2}/\d{1,2}/\d{4}\s\d{1,2}:\d{1,2}:\d{1,2}\s(A|P)M)";
        var matches = Regex.Matches(s, pattern);
        if (matches.Count > 0)
        {
            JToken last_json = null;
            try
            {
                var text = matches[matches.Count - 1].Groups["body"].Value;
                last_json = JToken.Parse(text);
                WriteLine(last_json.ToString());
            }
            catch (Exception ex) { WriteLine(ex.ToString()); }
        }
        else
        {
            WriteLine("No matches found");
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-06
      • 2020-09-13
      • 1970-01-01
      相关资源
      最近更新 更多