Разобрать строку / stringbuilder в классе, как мне это сделать? - PullRequest
1 голос
/ 25 мая 2011

Все данные, которые я должен проанализировать, в настоящее время хранятся в StringBuilder, и я хотел бы проанализировать их в моем списке классов:

StringBuilder data = new StringBuilder(length);

Итак, мой класс назначен списку:

public class Messages
{
    public DateTime Sent { get; set; }
    public string User {get; set; }
    public MessageType TypeUsed { get; set; }
    public string Message { get; set; }
}

public enum MessageType
{
    System,
    Info,
    Warn
}

public List<Messages> myList = new List<Messages>();

Теперь вот несколько примеров сообщений, которые мне нужно проанализировать:

[13:49:13] [System Message] <Username>  has openned blocked website 
[13:49:14] <Username> accessed file X
[13:52:46] [System Message] <Username>  has entered this room 
[13:52:49] [System Message] <Username>  has left this room 

Я сомневаюсь, что это будет лучший способ для его анализа.

Время присутствуетво всех сообщениях.Usernaem всегда с <> Когда нет [System Message] или [Warn Message], это сообщение типа Info.Сообщение - остальной пример:

has left this room
accessed file X
has openned blocked website

Теперь вот где я все еще думаю, что использовать.

Я мог бы использовать регулярное выражение для извлечения каждой строки примерно так:

Regex getData = new Regex(@"^\[(\d{1,2}:\d{1,2}:\d{1,2})\] \[([A-Za-z]+)\] ");

Но тогда мне в основном нужно было бы сделать несколько проверок для каждого сообщения, чтобы мне было не очень удобно с ним.

Например, мы думали об использовании split:

string line = item.Replace("[", "").Replace("]", "");
string[] fields = line.Split(' ');

итогда я бы проверил, что разделенные случаи было бы легко обнаружить MessageType, но я не настолько надежен, как мне кажется.

Я хотел бы получить несколько советов и идей о том, как я мог бы это сделать?1032 * Возможно, я просто слишком усложняю логику: /

1 Ответ

2 голосов
/ 25 мая 2011

Регулярное выражение, вероятно, наиболее удобно здесь.Попробуйте это:

^\[(\d{2}:\d{2}:\d{2})\]\s*(\[(System|Warn)[\w\s]*\])?\s*<([^>]*)>\s*(.*)$

Перевод:

  • Начиная с начала строки, сопоставьте [##: ##: ##] с группой захвата 1
  • Затем при необходимости сопоставьте спецификаторы System / Warn с группой захвата 2 и 3 (2 содержит весь текст в скобках, 3 - только ключевое слово System / Warn)
  • Затем введите имя пользователя внутри угловых скобок в группу захвата4
  • И, наконец, текст сообщения в группе 5

Проверяя содержимое группы 2 или 3 для каждой строки, вы узнаете, какой это тип сообщения.Все остальные поля готовы к использованию прямо из групп захвата.

Обновление:

Вот пример кода, как указано выше:

var regex = new Regex(@"^\[(\d{2}:\d{2}:\d{2})\]\s*(\[(System|Warn)[\w\s]*\])?\s*<([^>]*)>\s*(.*)$");
var input = new[]
    {
        "[13:49:13] [System Message] <Username>  has openned blocked website", 
        "[13:49:14] <Username> accessed file X",
        "[13:52:46] [System Message] <Username>  has entered this room",
        "[13:52:49] [System Message] <Username>  has left this room"
    };

foreach (var line in input) {
    var match = regex.Match(line);
    if (!match.Success) {
        throw new ArgumentException();
    }

    Console.WriteLine("NEW MESSAGE:");
    Console.WriteLine("     Time: " + match.Groups[1]);
    Console.WriteLine("     Type: " + match.Groups[2]);
    Console.WriteLine("     User: " + match.Groups[4]);
    Console.WriteLine("     Text: " + match.Groups[5]);

}
...