Using Regex to parse a chat transcript
You can always break it down in multiple lines to make it more readable. You can also use named groups which take the "magic" out of the group numbers (4 == whisper, 3 == normal, etc).

        var regex = new Regex(@"^\[(?&lt;TimeStamp&gt;\d{2}:\d{2}:\d{2})\]\s*" +
            @"(?:" +
                @"(?&lt;SysMessage&gt;\[System Message\])?\s*" +
                @"&lt;(?&lt;NormalWho&gt;[^&gt;]*)&gt;|" +
                @"(?&lt;Whisper&gt;(?&lt;WhisperWho&gt;.+) Whisper You :))\s*" +
            @"(?&lt;Message&gt;.*)$");

        string data = @"[02:33:03] John Whisper You :  Heya
[02:33:03] John Whisper You :  How is it going
[02:33:12] &lt;John&gt; [02:33:16] [System Message] bla bla
[02:33:39] &lt;John&gt; heya
[02:33:40] &lt;John&gt; hello :S
[02:33:57] &lt;John&gt; hi
[02:33:57] [System Message] &lt;John&gt; has left the room 
[02:33:57] [System Message] &lt;John&gt; has entered the room";

        foreach (var msg in data.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries))
        {
            Match match = regex.Match(msg);
            if (match.Success)
            {
                if (match.Groups["Whisper"].Success)
                {
                    Console.WriteLine("[whis from {0}]: {1}", match.Groups["WhisperWho"].Value, msg);
                }
                else if (match.Groups["SysMessage"].Success)
                {
                    Console.WriteLine("[sys msg]: {0}", msg);
                }
                else
                {
                    Console.WriteLine("[normal from {0}]: {1}", match.Groups["NormalWho"].Value, msg);
                }
            }
        }