扱っている言語がどれほど複雑かによって異なります。
分割
これは機能する場合に優れていますが、エスケープ規則がない場合にのみ機能します。たとえば、引用符で囲まれた文字列内のコンマは適切な分割ポイントではないため、CSV では機能しません。
フー、バー、バズ
分割できますが、
フー、「バー、バズ」
できません。
通常
正規表現は、「正規文法」を持つ単純な言語に最適です。Perl 5 の正規表現は、後方参照のためにもう少し強力ですが、一般的な経験則は次のとおりです。
(...)
ブラケット ( , ) または HTML タグのような他のネストに一致させる必要がある場合[...]
、正規表現だけでは十分ではありません。
正規表現を使用して、文字列を既知の数のチャンクに分割できます。たとえば、日付から月/日/年を抽出できます。ただし、複雑な算術式を解析するのは間違った仕事です。
当然のことながら、正規表現を書き、コーヒーを飲みに立ち去り、戻ってきて、書いた内容を簡単に理解できない場合は、自分が行っていることをより明確に表現する方法を探す必要があります。 電子メール アドレスは、正規表現を使用して正しく読みやすく処理できる限界に達している可能性があります。
文脈自由
パーサー ジェネレーターと手動でコーディングされたプッシュダウン/PEG パーサーは、ネストを処理する必要があるより複雑な入力を処理するのに最適です。これにより、ツリーを構築したり、演算子の優先順位や結合性を処理したりできます。
コンテキストフリーパーサーは、多くの場合、正規表現を使用して最初に入力をチャンク (スペース、識別子、句読点、引用符で囲まれた文字列) に分割し、次に文法を使用してそのチャンクのストリームをツリー形式に変換します。
CF 文法の経験則は次のとおりです。
正規表現が不十分で、言語内のすべての単語が事前の宣言に関係なく同じ意味を持つ場合、CF は機能します。
非文脈自由
言語の単語が文脈によって意味が変わる場合は、より複雑な解決策が必要です。これらはほとんどの場合、手作業でコーディングされたソリューションです。
たとえば、C では、
#ifdef X
typedef int foo
#endif
foo * bar
foo
が型の場合、 はという名前のポインタfoo * bar
の宣言です。それ以外の場合は、 という名前の変数によって名前が付けられた変数の乗算です。foo
bar
foo
bar