It's possible to use regex for this provided that you don't nest your statements. For example if your stmt1 is another case statment then all bets are off (you can't use regex for something like that, you need a regular parser).
Edit: If you really want to try it you can do it with something like (not tested, but you get the idea):
Regex t = new Regex(@"when\s+(.*?)\s+then\s+(.*?;)", RegexOptions.Singleline)
allMatches = t.Matches(input_string)
But as I said this will work only for not nested statements.
Edit 2: Changed a little the regex to include the semicolon in the last group. This will not work as you wanted - instead it will give you multiple matches and each match will represent one when condition, with the first group the condition and the second group the statement.
I don't think you can build a regex that does exactly what you want, but this should be close enough (I hope).
Edit 3: New regex - should handle multiple statements
Regex t = new Regex(@"when\s+(.*?)\s+then\s+(.*?)(?=(when|end))", RegexOptions.Singleline)
It contains a positive lookahead so that the second group matches from then to the next 'when' or 'end'. In my test it worked with this:
case a
when cond1
then stmt1;
stm1;
stm2;stm3
when cond2
then stmt2;
aaa;
bbb;
end case;
It's case sensitive for now, so if you need case insensitivity you need to add the corresponding regex flag.