【问题标题】:Parse string/stringbuilder into class, how should I go about it?将字符串/字符串生成器解析为类,我该怎么做?
【发布时间】:2011-05-25 17:46:44
【问题描述】:

我必须解析的所有数据当前都存储在 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 始终使用&lt;&gt; 当没有[System Message][Warn Message] 时,它是信息类型消息。 消息是剩下的例子:

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]+)\] ");

但是我基本上需要对每条消息进行多次检查,所以我对它不太满意。

例如考虑使用拆分:

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

然后我会检查拆分案例会很容易检测到 MessageType 但我认为不是那么可靠。

我想要一些建议和想法,以了解我如何才能做到这一点?

也许我只是让逻辑过于复杂:/

【问题讨论】:

    标签: c# string parsing class .net-3.5


    【解决方案1】:

    正则表达式在这里可能是最方便的。试试这个:

    ^\[(\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]);
    
    }
    

    【讨论】:

    • +1 非常详细,听起来很酷我最初考虑使用正则表达式,但后来我陷入了没有 [System *] 信息的情况,我会检查您的示例,谢谢。
    • @Prix:为方便起见,我添加了一些示例代码,请查看。
    猜你喜欢
    • 1970-01-01
    • 2011-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多