上传 使用 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 字符串内联,也可能在下一行。
我会使用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;
}