tags:

views:

124

answers:

4

Hello, I am new to c#. I need to write a method that takes a log file created by a compilation output and figures out the number of errors and warnings. I need to scan each line of the log and find the following match: x error(s), y warning(s)

Examples of this patterns are:

 Compile complete -- 1 errors, 213 warnings

 6>Process_Math - 3 error(s), 1 warning(s)
 24>Process_Math - 1 error(s), 0 warning(s)

How can I write the algorithm that finds that pattern and extract x and y from the line? Thanks Tony

+2  A: 

Here is a small example:

using System;
using System.Text.RegularExpressions;

class Program
{
    static void Main()
    {
     String input = @"Compile complete -- 1 errors, 213 warnings

        6>Process_Math - 3 error(s), 1 warning(s)
        24>Process_Math - 1 error(s), 0 warning(s)";

     Regex regex = new Regex(@"(\d+)\serrors?,\s(\d+)\swarnings?",
      RegexOptions.Compiled |
      RegexOptions.CultureInvariant |
      RegexOptions.IgnoreCase |
      RegexOptions.Multiline);

     Match match = regex.Match(input);

     if (match.Success)
     {
      Console.WriteLine("errors: " + match.Groups[1].Value);
      Console.WriteLine("warnings: " + match.Groups[2].Value);
     }
    }
}

This will grab the errors and warnings from the first line, not the subsequent ones.

Here is a commented version of the regular expression to help explain how it works:

(\d+)     # capture any digit, one or more times
\s        # match a single whitespace character
errors?,  # match the string "error" or "errors" followed by a comma
\s        # match a single whitespace character
(\d+)     # capture any digit, one or more times
\s        # match a single whitespace character
warnings? # match the string "warning" or "warnings"
Andrew Hare
Thanks for the quick reply. How can I extract the numbers? Could you show how to use it?Thanks
tony
Do you need the errors and warnings from the subsequent lines or do you just need the numbers from the roll-up on the first line?
Andrew Hare
+1  A: 
int errors = 0;
int warnings = 0;

Regex regexObj = new Regex(@"(?<errors>\d+) error\(s\), (?<warnings>\d+) warning\(s\)", RegexOptions.Multiline);
Match matchResults = regexObj.Match(input);
while (matchResults.Success) 
{
 errors = errors + Convert.ToInt16(matchResults.Groups["errors"].Value);
 warnings = warnings + Convert.ToInt16(matchResults.Groups["warnings"].Value);
 matchResults = matchResults.NextMatch;
}
Lieven
I think you have an errant curly brace in the while loop between the second and third lines. Also, you need to Convert.ToInt16 the Values if you want to add them.
bill weaver
I tested this code and works just fine (with the brackets correction and the Convert.ToInt16. Thanks to all for your help. Tony
tony
@bill weaver - fixed errors based on your comments.
Lieven
A: 

Having never done any work in C#, I can only advise on the regular expression itself:

^\d*>?(Compile complete|Process_Math) -{1,2} (\d+) error\(?s\)?, (\d+) warning\(?s\)?

This matches a string that might begin with a number, captures the leading text into the first capturing group, and captures the number of errors & warnings into the second and third capturing groups, respectively.

Drew Stephens
A: 

This example works well for errors:

using System;
using System.Text.RegularExpressions;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string compilationOutput =
                "Compile complete -- 1 errors, 213 warnings" +
                "Compile complete -- 2 errors, 213 warnings" +
                "Compile complete -- 3 errors, 213 warnings" +
                "Compile complete -- 4 errors, 213 warnings";

            string pattern = @"(\d+) error(:?s)?";

            MatchCollection results = Regex.Matches(compilationOutput, pattern, RegexOptions.IgnoreCase);

            int errors = 0;
            foreach (Match m in results)
            {
                int error;
                if (int.TryParse(m.Groups[1].Value, out error))
                {
                    errors += error;
                }
            }
        }
    }
}
Michael Alves