0

だから私は次の形式のテキストファイルをアップロードして解析しようとしています:

3月29日19:23:51,667 | DEBUG | 1 | 1:loremipsumを初期化しています...
3月29日19:23:31,682 | ERROR | 1 | 1:Foo.Bar.LauncherSystem.Blahの起動中にLorem.Ipsum.Exceptionが発生しまし
た。 LoremException:Lorem ipsum dolor sit amet、consectetur adipisicing elit ...
    at System.Lorem.Ipsum.Dolor.foo()
    at System.Lorem.Ipsum.Dolor.foo()
...
Mar 30 22:23:23,667 | DEBUG | 1 | 1:loremipsumを初期化しています...
Apr 02 17:24:17,413 | ERROR | 4 | 4:Loremがipsumに失敗しました... System.DolorException:オブジェクト参照がオブジェクトのインスタンスに設定されていません。
    Lorem.Ipsum.Dolor.IpsumDbController..ctor()で

そして、Errorクラス:

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

2つのエラーがある場合:

エラー1

3月29日19:23:33-は日付
System.Blah.LoremException-はErrorTypeです。
Lorem ipsum dolor sit amet、consecteturadipisicingelit-は説明です

エラー2

Apr0217:24:17-
DateSystem.DolorException-はErrorTypeです。
オブジェクト参照がオブジェクト インスタンスに設定されていません。-説明

文字列を解析する簡単な方法はありますか(正規表現を使用するかどうか)?文字列にERRORが含まれている場合は文字列を分割し、次の行を取得してErrorTypeに割り当てることを考えていました。

これをどうすればいいのかよくわからないので、助けていただければ幸いです。

更新:パターンは本当に一貫性がないので、String.Splitソリューションにはあまり自信がありません。

一般的なルールは次のとおりです。

すべて|エラー| Date (文字列Date)、System.blah.LoremException (ErrorType)の後に、Exceptionメッセージ(Description)が続きます。

ErrorType&Descriptionは、ERROR文字列とインラインであるか、次の行にある可能性があります。

4

4 に答える 4

1

私はあなたが考えているようにします。の各行を分割し|、2番目の要素が等しいかどうかを確認し、等しい場合は、ERRORその行と次の行を処理する必要があると想定します。

于 2012-05-10T15:49:05.720 に答える
1

ループでそのようなものを使用する場合...前に述べたように分割を使用することもできますが、そのようなものはもう少し効果的かもしれません

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


                if (data)
                    //here you deal with the following line
于 2012-05-10T15:55:38.040 に答える
1

解析を処理するために、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;
    }

この背後にあるロジックは、基本的に、正規表現に一致するものを1行ずつストリームごとに検索することです。正規表現自体は「ERROR」行のみに適合するように調整されているため、「DEBUG」などでは一致しません。

行が式と一致する場合、新しい「エラー」クラスインスタンスがリストに追加され、正規表現からの解析された値がフィールドに入力されます。「ErrorType」フィールドに入力するには、一致に続く次の行を読み取るだけです。

編集

さて、私が見ることができる最良の方法は、例外が同じ行にあるときにエラーメッセージの最後にある「...」を一致させてから、さらに一致させようとすることです。

改訂されたコード:

    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;
    }
于 2012-05-10T16:07:51.467 に答える
0

私はそれを解決しましたが、それは最もエレガントな解決策ではありません。他に回答があれば、ここに投稿してください。

    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;

    }
于 2012-05-14T10:07:45.080 に答える