式をその部分に分解してみましょう。
^
行の先頭から開始します。
(?:(2\d\d\d)\s+)?
年が表示された場合は、グループ 1 でキャプチャします (グループ 0 がすべてです)。年号がなくても構いません。
(?:Comm\. Rep\.\s+)?
文字列「Comm. Rep.」を受け入れます。および 1 つ以上の空白文字を含みますが、キャプチャしません。なくても構いません。
(?:CONG\s+)?
文字列「CONG」と 1 つ以上の空白文字を受け入れますが、キャプチャしません。なくても構いません。
(\S+)\s+(\S+)\s+
それぞれに少なくとも 1 つの空白が続く、少なくとも 1 文字の長さの非空白文字の 2 つのブロックが存在する必要があります。グループ 2 と 3 のブロックをキャプチャします。
(?:No\.\s+)?
文字列「いいえ」を受け入れます。および 1 つ以上の空白文字を含みますが、キャプチャしません。なくても構いません。
(\S+)
少なくとも 1 つの非空白文字の別のブロックが存在する必要があります。グループ 4 でキャプチャします。
(?:\s+\(.*?\))?
括弧内にある限り、少なくとも 1 つの空白の後に何かが続くことを受け入れますが、それをキャプチャしないでください。なくても構いません。
$
次に、行を終了する必要があります。
パーツが現在の一致にどのようにマップされるかを次に示します (行頭と行末は省略します)。
2009 IA H.B. 184 (NS)
---- ------- --- ----
2 5 7 8
2 つの「ブロック」しか受け入れられないため、問題は式のパート 5 にあります。
2009 IA HEART RATE 184 (NS)
---- ------------- --- ----
2 ??? 7 8
文字列「HEART RATE」も 3 番目のグループに入る必要があると仮定すると、5 番目の部分を次のように置き換える必要があります。
(\S+)\s+
少なくとも 1 つの空白以外の文字とそれに続く少なくとも 1 つの空白のブロックを受け入れ、それをグループ 2 (変更なし) でキャプチャします。
と
(.+?)\s+
グループ 3 の最後の空白を除くすべての空白をキャプチャします。
したがって、全体として必要な式は次のとおりです。
^(?:(2\d\d\d)\s+)?(?:Comm\. Rep\.\s+)?(?:CONG\s+)?(\S+)\s+(.+?)\s+(?:No\.\s+)?(\S+)(?:\s+\(.*?\))?$
ところで、私はhttp://regexpal.comにとても満足しています。
PS: Carl Walsh のソリューションは、貪欲でない (または怠惰な) キャプチャに依存しないため、パフォーマンスに関しては少しスマートです。