2016-11-03 6 views
0

У меня есть программа на C#, которая проходит через журналы SAS, и я хочу, чтобы она вытащила строки с ошибкой.Регулярное выражение для нескольких строк

Например, если мой файл журнала содержит следующие строки:

WARNING: Apparent invocation of macro EDIT_TEXT not resolved. 

ERROR 180-322: Statement is not valid or it is used out of proper order. 

ERROR: SAS ended due to errors. 
    You specified: OPTIONS ERRORABEND;. 
ERROR: Errors printed on page 4. 

NOTE: SAS Institute Inc., SAS Campus Drive, Cary, NC USA 27513-2414 
NOTE: The SAS System used: 
    real time   1.37 seconds 
    cpu time   0.38 seconds 

Я хочу, чтобы вернуться

ERROR: SAS ended due to errors. You specified: OPTIONS ERRORABEND;. 
ERROR: Errors printed on page 4. 

но возвращает только

ERROR: SAS ended due to errors. 

Это код, который я с использованием:

Match match; 
Regex regex; 
StreamReader sr; 
string log; 

sr = new StreamReader(path + ".log"); 
log = sr.ReadToEnd(); 
sr.Close(); 
regex = new Regex("ERROR: [^\\r]+\\r"); 
match = regex.Match(log); 

Я не уверен, что изменить на регулярном выражении, чтобы исправить это. Thanks

+1

Используйте [ '(м?)^ОШИБКА:. * (?: \ n (?! ERROR:). *) * '] (http://regexstorm.net/tester?p=%5eERROR%3a+.*%28%3f%3a%5cn%28%3f! ERROR% 3a +% 29. *% 29 * & я = ERROR% 3a + SAS + закончилась + из-за + к + ошибок.% 0D% 0A +++ Вы + указанный% 3a + OPTIONS + ERRORABEND% 3б.% 0D% 0aERROR% 3a + ошибки + + на печатной странице + + 4. & о = м). Или, split with '(? M)^(? = ERROR:)' –

+0

Как регулярное выражение может знать, что следующая строка относится к сообщению об ошибке? Это потому, что это отступы? Я думаю, вам нужно предоставить более крупный пример, который также содержит строки, которые вы не хотите извлекать, иначе будет сложно найти правило, которое работает. –

+0

Привет, Тим, я обновил свой оригинальный пост с большим количеством текста из журнала. –

ответ

0

Вы можете попробовать это Regex. Если у вас есть больше, чем ПРИМЕЧАНИЕ: или ОШИБКА: вы должны добавить их аналогичным образом.

ERROR:(.*\n?.*)(NOTE:|ERROR:)?

И это регулярное выражение имеет информацию об ошибке, хранящуюся в группе 1.

Во-вторых, не регулярное выражение подход:

string yourLogText = "you log text"; 

    string[] lines = yourLogText.Split(new string[1] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); 
    string builtErrorText = ""; 
    Boolean isBuildingError = false; 

    List<String> resultingErrors = new List<string>(); 
    for (int i = 0; i < lines.Length; i++) 
    { 
     if (lines[i].StartsWith("ERROR:")) 
     { 
      isBuildingError = true; 

     if (!String.IsNullOrEmpty(builtErrorText)) 
       resultingErrors.Add(builtErrorText); 

      builtErrorText = lines[i]; 
     } 
     else if (lines[i].StartsWith("NOTE:") || lines[i].StartsWith("WARNING:")) 
     { 
      isBuildingError = false; 
      if (!String.IsNullOrEmpty(builtErrorText)) 
       resultingErrors.Add(builtErrorText); 
     } 
     else if (isBuildingError) 
     { 
      // If you want them to appear on different lines. 
      builtErrorText += Environment.NewLine + lines[i]; 
     } 
     } 
    } 

    // In case it ends with an error 
    if (String.IsNullOrEmpty(builtErrorText)) 
     resultingErrors.Add(builtErrorText); 
+0

Что делать, если имеется более двух строк, относящихся к 1 ошибке? Что делать, если между линиями ERROR существуют линии WARNING? –

+0

Я не уверен, что все, что вы хотите, можно сделать с помощью одного регулярного выражения. Я добавил второе решение, которое не использует регулярное выражение, но оно работает, и вы можете адаптировать его к вашим потребностям. –

+0

Спасибо, Лупу. У меня есть работа с этой «ОШИБКОЙ:. * (?: \ N). *». Если это не сработает, я буду использовать ваш подход, не относящийся к регулярному выражению. спасибо –

Смежные вопросы