0

多くの奇妙なデータを含むいくつかのファイルに対して実行されるプロセスがあります。このプロセスでは、文字列を見つけて別のものに置き換える必要があります。関数は次のとおりです。

 private static string ReplaceRegex(string inputText, string regex, string replacement)
        {
            return (replacement != null)?new Regex(regex, RegexOptions.IgnoreCase).Replace(inputText, replacement).Trim(): string.Empty;
        }

ほとんどの場合、これは適切に機能しますが、この関数に 3491 文字の長さの inputText と、この文字列を正規表現として渡すと、次のようになります。

"\[HYPERLINK\]\s*(?:\<[\s\S]*?\>)*\s*([\s\S]*?)\s*(?:\<[\s\S]*?\>)*\s*\[\/HYPERLINK]\s*(?:\<NO1\>)?\s*(?:\<WC1?\>)?\s*\[URL\]\s*(?:\<NO1?\>)?\s*(?:\<WC1?\>)?\s*([\s\S]*?)\s*(?:\<NO1?\>)?\s*(?:\<WC1?\>)?\s*\[\/URL\](?:\<NO1?\>)?(?:\<WC1?\>)?"

プロセスが停止します。

システムが OutOfMemory 例外をスローするのを待っていましたが、そうではなく、スタックするだけです。何時間も応答を待っていましたが、応答しませんでした。

これを解決する方法はありますか?

編集:みんなありがとう。

正直なところ、私はこのコードをプロジェクトに継承し、現在何が起こっているのかを把握しようとしています。そして、なぜ誰かがこのようにしたのかわかりません。

4

6 に答える 6

4

「壊滅的なバックトラッキング」と呼ばれるものがあります。

基本的に、可変長式 ( *+など) の後に「重複」する (つまり、両方の式が同じ文字セットで一致する可能性がある) 可変長式がある場合、二つの表現。これは通常、式全体が失敗し、.NET 正規表現エンジンが重複する式間で入力テキストをシフトしようとした場合にのみ発生するため、テストで見逃されることがよくあります。

あなたの式には、これを引き起こす可能性のある多くのサブ式がありますが、例を次に示します。

\s*([\s\S]*?)

最初の部分 は\s*、0 個以上の空白文字に一致します。2 番目の ,[\s\S]*?は、(非空白文字に加えて) 0 個以上の空白文字にも一致します。これにより、入力が最初の試行で失敗し、一致する空白文字が複数ある場合に、壊滅的なバックトラッキングが発生します。

ここでもこの問題について少し書きました:
どうすれば邪悪な正規表現を認識できますか?

于 2013-09-20T18:00:45.143 に答える
0

をたくさん使用していることが関係している可能性があります*。特にそのような大規模なものを作成する場合、すべてのリソースを消費してシステムを機能不全に陥れる可能性のある正規表現を作成するのは非常に簡単です。

個人的には、そこにいくつかの制限を追加してみます ( など.{1,100})。

于 2013-09-20T15:56:39.690 に答える
0

*(ゼロ以上) の使用をやめ、そこにデータがあることがわかっているときに (1 つ以上)を使用して、パーサーにより良い処理のヒントを与えます。or+タイプの状況でのみ使用*してください。これは、失敗して何も含まれないようにしたくない場合に使用してください。

于 2013-09-20T18:13:42.153 に答える