I would use an expression for each of the numbers. You could do all in one using named groups, but three is easier to manage.
I'll use positive lookaheads and behinds for the capture:
private Regex FailsRegex = new Regex(@"(?<=Number of: Fails \()\d*(?=\))");
private Regex AbortsRegex = new Regex(@"(?<=Aborts \()\d*(?=\))");
private Regex WarnsRegex = new Regex(@"(?<=Warnings \()\d*(?=\))");
let me break these down for you:
Three parts:
Non Captures LookBehind: (?<=Number of: Fails \()
Captured digits \d*
Non Captured LookAhead: (?=\))
The LookBehind "(?<=[regex]) checks the string before the captured part. In this case I use the text AND the bracket, which is escaped "\("
The capture \d* looks for zero to infinite digits [0-9]
The LookBehind "(?=[regex]) looks at the string after the captured part. in this case just the close bracket "/)"
Hope that helps ^_^
Andy
UPDATE:
Added the @ at the beginning of the regex strings.
The /d char is a valid escape sequence for a regex but not for a string. Each Regex escape would need to be escaped. The @ symbol is shorthand for this:
@"(?<=Number of: Fails \()\d*(?=\))" = "(?<=Number of: Fails \\()\\d*(?=\\))"
UPDATE:
Some ideas that do not involve Regex:
string[] items = s.Split(';');
int fails = int.Parse(items[0]);
int aborts = int.Parse(items[1]);
int warns = int.Parse(items[2]);
string fails = s.Substring(s.FirstIndexOf("("),s.FirstIndexOf(")") - s.FirstIndexOf("(");
They're your best options ^_^