PCRE has builtin support for this kind of factoring, too:
(?(DEFINE)
(?<code>
[A-Z]*H # prefix
\d+ # digits
[a-z]* # suffix
)
(?<multicode>
(?: \( \s* )? # maybe open paren and maybe space
(?&code) # one code
(?: \s* \+ \s* (?&code) )* # maybe followed by other codes, plus-separated
(?: \s* [\):+] )? # maybe space and maybe close paren or colon or plus
)
)
( (?&multicode) ) # code (capture)
( .*? ) # message (capture): everything ...
(?= # ... up to (but excluding) ...
(?&multicode) # ... the next code
(?! [^\w\s] ) # (but not when followed by punctuation)
| $ # ... or the end
)