4

preg_match_allを使用して、読み込んでいるファイルを検索しています。ファイルには次の形式の行が多数含まれており、タグ間の数字を抽出しています。

<float_array id="asdfasd_positions-array" count="6">1 2 3 4 5 6</float_array>

私はpreg_match_allを使用していますが、これは正常に機能しています。ただし、ファイルをこれまでのところ通過して停止しているように見えます。

preg_match_all("/\<float_array id\=\".+?positions.+?\" count\=\".+?\"\>(.+?)\<\/float_array\>/",$file, $results);

ファイルは90,000行で、サイズは約8MBです。抽出された文字列の3つおきの数値を編集し、str_replaceを使用してファイルに編集し直しています。その後、ファイルが再度書き込まれます。ここで完全なスクリプトを参照してください。

http://pastie.org/4300537

スクリプトはエントリの約半分を正常に置き換えており、ファイルの後半では何もしていません。編集に成功した行をファイルの上位からコピーしてさらに下に貼り付けました...ファイル内でそれ以上編集されませんでした。配列がいっぱいの場合と同じですが、memory_limitが500Mに設定されています。

何か案は?

編集:解決策が見つかりました

問題が見つかりました。タグ間の文字列のサイズが大きすぎる場合があり、スキップされました。PHPで制限を見つけました。pcre.backtrack_limitは100000に設定されており、一部の文字列はこれより大きくなっています。そこで、次の行を使用して.htaccessファイルでこれを増やしたところ、機能するようになりました。

php_value pcre.backtrack_limit 5000000

4

2 に答える 2

2

メモリが問題であり、実行時間の制限ではない場合は、遅い解決策 (行ごと) に進みます >>

$fi = fopen("data.txt",  "r");
$fo = fopen('data2.txt', 'w');
while (!feof($fi)) {
  $line = fgets($fi);

  # regex stuff here

  fwrite($fo, $line);
}
fclose($fi);
fclose($fo);
于 2012-07-22T14:27:31.493 に答える
0

このような単純なパーサーを使用してテキストファイルを解析することを検討してください>>

$fi = fopen("data.txt",  "r");
$fo = fopen('data2.txt', 'w');
$status = 0;
do {
  $data = stream_get_line($fi, PHP_INT_MAX, ">");
  if ($status == 1) {
    preg_match("/(.*)<\/float_array$/", $data, $m);
    $status--;
    if (sizeof($m) != 0) {
      fwrite($fo, $m[1] . "\n");
      continue;
    }
  }
  if ($status == 0) {
    preg_match("/<float_array[^>]*?\bid\s*=\s*[\"'][^\"']*?positions[^\"']*?[\"'][^>]*?\bcount\s*\=[^>]*?$/", $data, $m);
    if (sizeof($m) > 0) {
      $status++;
    }
  }
} while (!feof($fi));
fclose($fi);
fclose($fo);
于 2012-07-22T18:12:26.677 に答える