Terence, Break your regex into logical pieces. Assign each piece to a variable (or constant) whose name describes it. Catenate the variables together to create the finished string. (This might run at compile time.) Your regex is now human-readable (looks more like BNF), and each piece can be inspected visually by itself to see if it matches the variable-name description. Eg, your ^\w+([-+.']\w+)@\w+([-.]\w+).\w+([-.]\w+)*$ becomes the pseudocode (doubling up the \s): word = "\w+" addressee_separator = "[-+.']" addressee = word + optional_repeat(addressee_separator + word) domain_separator = "[-.]" domain_part = word + optional_repeat(domain_separator + word) domain = domain_part + "\." + domain_part address = "^" + addressee + "@" + domain + "$" where function (or macro) optional_repeat(x) returns "(" + x + ")*" (or you can spell it out if you don't want the reader to have to consult the definition of optional_repeat()). NB. This is code, so comments can be included! Adjust verbosity according to taste, or wizardry comfort level. Critique: I don't like that your regex confuses the optional .s and the compulsory . in the domain name, making the grammar ambiguous. The ambiguity is revealed by the definition of domain, the like of which no one should be using in a well-constructed grammar. 🙂 IMHO, better would be: ... word_with_hyphen = word + optional_repeat("-" + word) domain = word_with_hyphen + compulsory_repeat("\." + word_with_hyphen) ... Cheers, Paul