Удаление заголовка из отформатированной строки - PullRequest
0 голосов
/ 09 января 2019

У меня есть отформатированный файл журнала, который я пытаюсь проанализировать; файл разделен на разделы с заголовком, а данные внутри каждого раздела отформатированы в формате JSON следующим образом. Ссылка на извлечение файла журнала здесь

[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;
    }

Проблема в том, что я t оставляет заголовок на месте, который мне нужно удалить перед десериализацией JSON, и он склонен к разрыву, потому что названия разделов не настолько уникальны и они могут быть повторены далее как заголовки без заголовка (как видно из моего примера). Кроме того, я не знаю, как остановиться в конце нужного мне раздела, прежде чем начнется другой.

Я думал, что можно использовать RegEx, но это кажется большим, даже для RegEx, и, возможно, есть лучшее решение.

Ответы [ 2 ]

0 голосов
/ 10 января 2019

Если лог совпадает с , найденным в 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; }
    }
}
0 голосов
/ 09 января 2019

Надеюсь, это то, что вам нужно. :) На самом деле, regex находит 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");
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...