PHP - preg_match_all没有搜索完整的字符串?

时间:2012-07-22 14:14:55

标签: php regex str-replace preg-match-all

我使用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。我正在编辑提取的字符串中的每三个数字,并使用str_replace将其编辑回文件。然后再次写入该文件。请参阅此处的完整脚本;

http://pastie.org/4300537

脚本成功替换了大约一半的条目,并且没有对文件的后半部分做任何事情。我甚至从文件中的较高位置复制了一个成功编辑的行并进一步向下粘贴......并且它没有在文件中进一步编辑。好像数组如果已满但memory_limit设置为500M。

有什么想法吗?

编辑:找到解决方案

我发现了问题 - 标签之间的字符串大小在某些情况下太大而被忽略了。我在PHP中找到了限制。 pcre.backtrack_limit设置为100000,某些字符串大于此值。所以我使用以下行在.htaccess文件中增加了它,现在它可以工作。

php_value pcre.backtrack_limit 5000000

2 个答案:

答案 0 :(得分:2)

如果 内存是一个问题 而不是执行时间限制,那么请选择慢速解决方案(逐行)&gt;&gt;

$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);

答案 1 :(得分:0)

您可以考虑使用这样的简单解析器 解析 您的文本文件&gt;&gt;

$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);