UL
PHP preg_replace を使用して、ネストされている可能性のある HTML を CSV (4 フィールド) に変換すると、問題が発生します。次の行は、最上位の UL から作成されたフィールドの 1 つに (削除された改行を除いて) 変更されないネストされたリストの一部を処理します。
$idx_string = preg_replace("|(<li>.*?)\n+(<ul>)\n+(.*?</li></ul></li>)|si","$1$2$3", $idx_string);
現在、ネストされたリストのないいくつかの大きなリスト(<ul>
変換のこの時点でそのようなものがないことを確認) では、これは backtrack_limit_error のために失敗します。そのため、それを乗り越える方法はわかっていますが、何も一致しないとバックトラック制限がトリガーされる方法がまったくわかりません。私が見つけたものによると、 preg_replace は新しい文字列または変更されていない古い文字列のいずれかを返します (エラーの場合は NULL/FALSE 以外)。では、バックトラックはどのようにここに入るのですか?
リスト項目は次のようになります。
<li><a href="9848.php">Algeria - Italy.</a></li>
<li>Go sailing<br>
<a href="11434.php">Anglesey / Wight / Guernsey / Jersey</a></li>
<li><a href="11367.php">d'Anjou et du Saumurois, Carte des Gouvernements</a><br>
Check out the old places!</li>
CSV は次のようになります。
|9848.php|Algeria - Italy.|
Go sailing|11434.php|Anglesey - Anglesey / Wight / Guernsey / Jersey|
|11367.php|d'Anjou et du Saumurois, Carte des Gouvernements|Check out the old places!
したがって、実際にはすべてのタグが取り除かれ、残りは 4 つのフィールドに分割されます。奇数のネストされたリストは、3 番目のフィールドにそのまま詰め込まれます。つまり、<ul>
&<li>
タグが付けられ、改行だけが取り除かれます。
これは、フォールバック メカニズムとして使用される古い PHP 4 コードです。DOMDocument
より良い一般的なアプローチかもしれませんが、私はこれに多くの時間を投資したくありません。リストの形式はかなり厳密でシンプルです。
まとめ
Jerry のコメントを念頭に置いてコードをもう一度見ると、最初のグループ(<li>.*?)
が PHP を<li>
ファイルの先頭の最初の右側から開始し、ファイル全体<ul>
を 1 つのバックトラック スペースに検索する方法が明らかになります。
ステートメントをif (stripos($idx_string, '<ul')) { ... }
ブロックで囲むと、pcre.backtrack_limit を 1000000 に引き上げるのと同様に、エラーが発生する可能性が減少します。これは PHP 5.3.7 のデフォルトですが、何らかの理由でここに更新されていません。以上で記録の締めくくりです。