【发布时间】:2012-07-21 00:11:53
【问题描述】:
我正在使用 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
【问题讨论】:
-
您是否将 PHP 执行时间限制设置为 0?大约 30 秒后,脚本将关闭,除非您指定它根据需要运行。
-
文件正在完全读入,因为
$file字符串最后被写入文件,并且完整的文件就在那里。脚本完全执行,我正在重置循环内的超时。如果我在最后一行回显就好了。 -
反斜杠太多(
<和=不需要)。也使用单引号。并进一步限制格式[\w-]+或\d+和[\d\s]*代替所有.+?。如果它是有效的 XML,也可以尝试 SimpleXML;简单得多,而且速度也不会慢很多。 -
感谢马里奥 - 更典型的 ID 类似于“10iHdUVMXDPhBIJhh1IGZa-positions-array”。你的建议会涵盖“”和“-”字符吗?这些字符的数量和位置也各不相同。
标签: php regex str-replace preg-match-all