Here is my take on the same, using Lambda expressions and slightly more advanced regular expression features:

I have not tested this code, so errors may exist.

This implementation will ignore unrecognized tokens.

namespace Postfix
{
class Parser
{
static Dictionary<string, Func<int, int, int>> operators;
static Regex parserEngine = new Regex(@"\G(\s+(?<op>[-+*/])|\s*(?<value>-?[0-9]+))", RegexOptions.ExplicitCapture);
static Parser()
{
operators = new Dictionary<string, Func<int, int, int>>();
operators["+"] = (a, b) => a + b;
operators["-"] = (a, b) => a - b;
operators["*"] = (a, b) => a * b;
operators["/"] = (a, b) => a / b;
}
static int parseExp(string s)
{
Stack<int> stack = new Stack<int>();
foreach(Match match in parserEngine.Matches(s))
{
if(match.Success)
{
foreach(KeyValuePair<string, string> m in match.Groups)
{
if(m.Key == "op")
{
if(stack.Count < 2)
throw new Exception("Invalid expression: out of stack.");
int b = stack.Pop();
int a = stack.Pop();
stack.Push(operators[m.Value](a, b));
}
else if(m.Key == "value")
stack.Push(int.Parse(m.Value));
}
}
}
if(stack.Count != 1)
throw new Exception("Invalid expression: not exactly one result on stack.");
return stack.Pop();
}
static void Main()
{
string exp = "23 5 - 12 *";
Console.WriteLine("expression '{0}' result is '{1}'", exp, Parser.parseExp(exp));
}
}
}