3

「スタック オーバーフロー」エラー (「スタック スペースが不足しています (アプリケーション エラー コード: 12246)」) について困惑しています。

(@article(((?!eprint|@article|@book).)*\r)*)pmid = {(.+)}((((?!eprint|@article|@book).)*\r)*(@|\r*\z))

と置き換えます

\1eprinttype = {pubmed}, eprint = {\4}\5

これらの同じパターンを手動で使用して、一度に 1 つずつ検索と置換を実行できます。一致が発生しなくなっても、エラーは発生しません。小さなファイルで作業することで、エラーを回避することもできます。

責任があるのは私の非効率的でずさんな正規表現コーディングであると思われます。これをより効率的に行うために専門家の助けをいただければ幸いです。BibLaTeX 文献目録で、まだフィールドを持っていないが、eprintフィールドを持っているすべてのエントリを見つけて、フィールドを対応する e-print 仕様にpmid置き換えようとしています (とを使用)。pmideprinteprinttype


更新:いくつかの実験の後、別のアプローチが唯一の方法であることがわかりました。探している

(?(?=@article(.+\r)+eprint = {(.+\r)+}\r*)(?!)|(@article(.+\r)+)pmid = {(.+)}((.+\r)+}\r*))

と置き換えます

\3eprinttype = {pubmed}, eprint = {\5}\6

トリックを行います。これに関する唯一の問題は、後方参照が壊れやすいことですが、名前付き後方参照を BBEdit で動作させることができません。

4

2 に答える 2

3

おそらく、この最後の部分によって引き起こされる壊滅的なバックトラックです。

.)*\r)*(@|\r*\z))

それを分解して単純化すると、基本的に.*\r*、および別のもの\r*が隣り合っています。ここ\rで、入力の最後にある一連の文字列を想像してください。それぞれをどの\rように配布する必要がありますか これらの小さな句のどれが各\rキャラクターを吸収しますか? を持っている場合は、パーツで\r\r\r\r\r5 つすべてを食べて、パーツでまったく食べないこともできます... または、まだ一致する任意の数の順列を作ることができます。は貪欲なので、最初に埋めようとしますが、それが失敗した場合は、そのうちの 1 つが機能するまで順列を試行し続ける必要があります。そのため、最終的にクラッシュするまで、不必要なバックトラッキングで大量のリソースを浪費している可能性があります。\r.*\r**.*

私は正規表現の最適化手法の専門家ではありませんが、私があなただったらそこから始めます。

アップデート:

PCRE に関するウィキペディアの記事をご覧ください。

「NoRecurse」PCRE ビルド オプション (別名「--disable-stack-for-recursion」) が選択されていない限り、呼び出し元のアプリケーションまたはオペレーティング システムによって適切なスタック領域が PCRE に割り当てられる必要があります。... PCRE のドキュメントでは、「NoRecurse」ビルド オプションを使用すると PCRE が代替オプションよりも遅くなることが警告されていますが、それを使用すると、スタック オーバーフローの問題が完全に回避されます。

したがって、ここでは壊滅的なバックトラックが良い賭けだと思います。PCREのビルドオプションを変更する前に、正規表現を微調整して解決しようと思います。

于 2012-03-31T07:30:26.367 に答える
0

明らかにこれはバグです。しかし、表現を少し変えてみてください。要件を知らずに式を最適化することは困難ですが、推測は次のとおりです。

(@article(?:(?:(?!eprint|@article|@book|pmid)[^\r])*+\r)*+)pmid = {([^\n\r]+)}((?:(?:(?!eprint|@article|@book)[^\r])*+\r)*(?:@|\r*\z))

と置換する:

\1eprinttype = {pubmed}, eprint = {\2}\3

BBEdit は、(非常に) 時代遅れでない限り、PCRE を使用しているようです。上記の表現は互換性があるはずです。

于 2012-03-31T12:06:36.893 に答える