上传 使用 MVC 3 解析文本文件 3 ASP.NET

本文关键字:文件 ASP NET 文本 使用 MVC 上传 | 更新日期: 2023-09-27 18:33:42

所以我正在尝试上传然后解析以下格式的文本文件:

3月 29 19:23:51,667|DEBUG|1 |1    : 初始化 lorem ipsum...
3月 29 19:23:31,682|错误|1 |1    : 启动 Foo.Bar.Launcher
时 Lorem.Ipsum.Exception System.Blah.LoremException: Lorem ipsum dolor sit amet, consectetur adipisicing elit...
    at System.Lorem.Ipsum.Dolor.foo((
    at System.Lorem.Ipsum.Dolor.foo((

3月 30 22:23:23,667|DEBUG|1 |1    : 初始化 lorem ipsum...
4月 02 17:24:17,413|错误|4 |4    :Lorem 无法求和...System.DolorException:对象引用未设置为对象的实例.
    at Lorem.Ipsum.Dolor.IpsumDbController..ctor((

和错误类:

public class Error
{
    public int ID { get; set; }
    public string Date { get; set; }
    public string Description { get; set; }
    public string ErrorType { get; set; }
}

其中有两个错误:

错误 1

3月29日 19:23:33 - 是日期
System.Blah.LoremException - 是 ErrorType。
Lorem ipsum dolor sit amet, consectetur adipisicing elit - 是描述

错误 2

Apr 02 17:24:17 - 是日期
System.DolorException - 是 ErrorType。
对象引用未设置为对象的实例。- 是描述
有没有一种简单的方法可以解析字符串(通过正则表达式?我正在考虑拆分字符串,如果它包含错误,然后获取下一行分配给 ErrorType。

我不太确定我会怎么做,所以任何帮助将不胜感激!

更新:模式确实不一致,所以我对 String.Split 解决方案没有信心。

一般规则是:

全部 |错误|将有一个日期(我们的字符串Date(,System.blah.LoremException(我们的错误类型(,后跟一个异常消息(我们的描述(

ErrorType & Description 可能与 ERROR 字符串内联,也可能在下一行。

上传 使用 MVC 3 解析文本文件 3 ASP.NET

我会使用StreamReader和正则表达式的组合来处理解析。

    private static List<Error> ParseErrors(string filepath)
    {
        Regex parser = new Regex(@"^(?<date>'w{3}'s'd{1,2}'s'd{1,2}(?::'d{1,2}){2}),[^'|]+'|ERROR'|[^:]+'s*(?<description>.+)$", RegexOptions.IgnoreCase | RegexOptions.Compiled);
        string line = string.Empty;
        Match curMatch = null;
        var errorLog = new List<Error>();
        using (StreamReader sReader = new StreamReader(filepath))
        {
            while (!sReader.EndOfStream && (line = sReader.ReadLine()) != null)
            {
                curMatch = parser.Match(line);
                if (curMatch.Success)
                {
                    errorLog.Add(new Error()
                    {
                        ID = errorLog.Count, /* not sure how you assign ids? */
                        Date = curMatch.Groups["date"].Value.Trim(),
                        Description = curMatch.Groups["description"].Value.Trim(),
                        ErrorType = sReader.ReadLine().Trim()
                    });
                }
            }
        }
        return errorLog;
    }

这背后的逻辑基本上是逐行循环搜索以查找与正则表达式的匹配项。正则表达式本身是专为适应"ERROR"行而定制的,因此它不会与"DEBUG"等匹配。

如果该行与表达式匹配,则会在列表中放置一个新的"Error"类实例,并使用正则表达式中的解析值来填充字段。要填写"错误类型"字段,我只需阅读匹配后的下一行。

编辑

好的,我能看到的最好方法是匹配尾随的"..."当异常在同一行上时,在错误消息的末尾,然后尝试进一步匹配。

修订后的代码:

    private static List<Error> ParseErrors(string filepath)
    {
        Regex parser = new Regex(@"^(?<date>'w{3}'s'd{2}'s'd{1,2}(?::'d{1,2}){2}),[^'|]+'|ERROR'|[^:]+:'s*(?<description>.+?)(?:'.'.'.'s*(?<type>.+))?$", RegexOptions.IgnoreCase | RegexOptions.Compiled);
        string line = string.Empty;
        Match curMatch = null;
        var errorLog = new List<Error>();
        using (StreamReader sReader = new StreamReader(filepath))
        {
            while (!sReader.EndOfStream && (line = sReader.ReadLine()) != null)
            {
                curMatch = parser.Match(line);
                if (curMatch.Success)
                {
                    errorLog.Add(new Error()
                    {
                        ID = errorLog.Count, /* not sure how you assign ids? */
                        Date = curMatch.Groups["date"].Value.Trim(),
                        Description = curMatch.Groups["description"].Value.Trim(),
                        ErrorType = (curMatch.Groups["type"].Success ? curMatch.Groups["type"].Value : sReader.ReadLine().Trim())
                    });
                }
            }
        }
        return errorLog;
    }

我会按照你的想法去做。拆分|上的每一行,检查第二个元素是否等于ERROR,如果是,假设我需要处理该行和下一行。

如果你在循环中使用类似的东西......你也可以使用我之前提到的拆分,只是这样可能会更有效一些

if (line.Contains("ERROR"))
                {
                    data = true;
                    continue;
                }

                if (data)
                    //here you deal with the following line

我有点解决了,但这不是最优雅的解决方案,所以如果您有其他答案,请随时在此处发布。

    public static List<Error> ParseErrors(string filepath)
    {
        //separated the two regex
        Regex dateRegex = new Regex(@"^'w{3}'s'd{2}'s'd{2}:'d{2}:'d{2}", RegexOptions.IgnoreCase | RegexOptions.Compiled);
        Regex errorRegex = new Regex(@"((?<type>System.*?Exception):'s(?<description>.*'.))", RegexOptions.IgnoreCase | RegexOptions.Compiled);
        string CurrentLine = string.Empty;
        string NextLine = string.Empty;
        List<Error> errorLog = new List<Error>();
        using (StreamReader sReader = new StreamReader(filepath))
        {
            while (!sReader.EndOfStream && (CurrentLine = sReader.ReadLine()) != null)
            {
                if (CurrentLine.Contains("|ERROR|"))
                {
                    Match DateMatch = dateRegex.Match(CurrentLine);
                    Match ErrorMatch = errorRegex.Match(CurrentLine);
                    string date = DateMatch.Groups[0].Value.Trim();
                    string errorType = string.Empty;
                    string description = string.Empty;
                    //Check if error type and description is residing in the current line, otherwise, check at the next line
                    if (!ErrorMatch.Groups["type"].Value.Equals("") && !ErrorMatch.Groups["description"].Value.Equals(""))
                    {
                        errorType = ErrorMatch.Groups["type"].Value.Trim();
                        description = ErrorMatch.Groups["description"].Value.Trim();
                    }
                    else
                    {
                        NextLine = sReader.ReadLine();
                        ErrorMatch = errorRegex.Match(NextLine);
                        errorType = ErrorMatch.Groups["type"].Value.Trim();
                        description = ErrorMatch.Groups["description"].Value.Trim();
                    }
                    Error NewError = new Error();
                    NewError.Date = date;
                    NewError.ErrorType = errorType;
                    NewError.Description = description;
                    //a bit lazy with the regex, just take the first sentence of the description if it has multiple sentences.
                    if (NewError.Description.Contains(". "))
                        NewError.Description = NewError.Description.Substring(0, NewError.Description.IndexOf(". "));
                    // Do not add if it's a custom exception.
                    if(!NewError.Description.Equals("") && !NewError.Description.Equals(""))
                        errorLog.Add(NewError);
                }
            }
        }
        return errorLog;
    }