Emacsのregexp実装は他の多くの類似する実装と同じように概ね堅牢ですが、2つの問題のいずれかを引き起こすことがあります。それはマッチングが内部スタックスペースを使い果たしてエラーをシグナルしたり、完了まで長時間を要するかもしれないという問題です。以下のアドバイスはこれらの症状を軽減して、発生する問題を緩和する助けとなるでしょう。
\`
)の使用による行、文字列、あるいはバッファー先頭のアンカーregexp。これは実装内部の高速パスを利用して、無駄なマッチングの試行を回避できる。これら以外のゼロ幅アサーションでも、早期にマッチを失敗させることによる利益が得られるかもしれない。
(これはトレードオフである。マッチに成功するorパターンは、もっとも頻繁にマッチするパターンを最初にすると実行が高速になる。)
ネストした繰り返しには特に注意。曖昧さが存在すると、それらのマッチングが非常に低速になるのは容易である。たとえば‘\(?:a*b*\)+c’は‘a’からなる適切な長さの文字列にたいするマッチ試行でも、失敗までに長時間を要するだろう。これと等価な‘\(?:a\|b\)*c’はより高速であり、‘[ab]*c’は更に良い。
rx
の使用を検討する(rx
構造化Rgexp表記を参照)。これはいくつかのorパターンを自動的に最適化するとともに、明示的に要求されなければキャプチャリンググループを決して導入しない。
上記アドバイスにしたがってなおregexpがスタックオーバーフローするようなら、ためらうことなくマッチングを複数の関数呼び出しで行い、それぞれの関数呼び出しではバックトラッキングが容易に含まれるように単純なregexpを使ってください。
regexpやregexpエンジン自体の問題の診断を助けるために、この関数はコンパイルされた形式のregexpを記述する文字列をリターンする。これを理解するためには最低限、Emacsのソースコードのファイルsrc/regex-emacs.c
にあるタイプre_opcode_t
の説明を読解できる必要があるかもしれない。
現在のところは--enable-checking
を指定してEmacsをビルドした場合のみ、意味のある記述を得ることができる。