問題は、あなたが実際にあなたの入力を説明する文法とは何かということです。すべてを一度に説明しようとすると、非常に複雑になり、非常に速くなります。別の方法については、 perlyappモジュールを参照してください。
ただし、正規表現のみを使用することを主張する場合は、次のようにします。
/^-MEMBER: # start of line, match specific string
\s+ # must be followed by at least one whitespace char
(\b[^,]+) # now we need to match a word in a capture group
(?:,\s(\b.{1,50}\b)\.?)? # here's the pain, so lets deal with it below
\s+ # more whitespace
ID#: # match this string
\s+ # and some more whitespace
(\d+)$/ # digits at the end of the line
(
?: # cluster the following
,\s # comma, then a single space
(
\b.{1,50}\b # up to fifty "things" bounded by words
) # another capture group
\.? # optional period
)? # zero or one of these I.E. optional capture
これは、仮定を「言語」にハードコード化するため、fragilです。ファーストネーム/ミドルネームがない場合、オプションのグループ内にあるため、コンマは許可されないことに注意してください。これが、2番目のテストが一致しないという問題です。
次に、ファーストネーム/ミドルネームのセクションがある場合は、改行以外のものを含めることができます。これはあなたが望むまたは期待するものではないかもしれません。
パーサーが有用である理由は、パーサーが「コンテキスト」を持つことを可能にするからではありませんが、それは可能です。これは、複雑な正規表現を、明確に定義された全体に接続された、小さくて管理しやすい部分に分割するためです。そのようなツールを学ぶことによって、あなたがここで抱えている問題のタイプは、実装し、変更するのが簡単になります。
正規表現が各セクションで「有効」なものを定義しようとしていることに注目してください。姓(\b[^,]+)
にはコンマ以外の名前を付けることができます。これは、あなたの望むことですか?有効な名前だけを含めることができる場合はどう[a-zA-Z_]
なりますか?;injectionattemptFTW!!;#
有効な名前ですか?限られた明白な条件のセットが存在するようにプログラムを設計します。If a then valid, else fail
単純なsについて推論するのは簡単a
です。
考えられるすべての特殊なケースを定義しない限り、この正規表現を壊すような事態に遭遇します。完全な正規表現を定義できないため、2つのオプションがあります。
- 特殊なケースが特定されると、正規表現をさらに複雑にパッチします
- 複雑な正規表現の必要性を回避するための再設計
オプション1を選択した場合、この正規表現は現在の問題を修正します。
/^-MEMBER:\s+(\b[^,]+),?(?:\s(\b.{1,50}\b)\.?)?\s+ID#:\s+(\d+)$/