我正在使用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);
该文件有90000行,大小约为8MB。我正在编辑提取字符串中的每三个数字,并使用str_replace将其编辑回文件中。然后再次写入该文件。请参阅此处的完整脚本;
http://pastie.org/4300537
脚本成功地替换了大约一半的条目,而没有对文件的后半部分做任何操作。我甚至从文件的更高位置复制了一行成功编辑的行,并粘贴到更下面。。。文件中没有对其进行进一步编辑。就好像数组已满,但memory_limit设置为500M。
有什么想法吗?
编辑:找到解决方案
我发现了问题-在某些情况下,标记之间的字符串太大,因此被跳过。我在PHP中找到了极限。pcre.backtrack_limit设置为100000,有些字符串比这个值大。因此,我在.htaccess文件中使用以下行增加了这一点,现在它可以工作了
php_value pcre.backtrack_limit 5000000
如果内存是一个问题而不是执行时间限制,则使用慢速解决方案(逐行)>>
$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);
您可以考虑使用类似这样的简单解析器来解析您的文本文件>>
$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);