迭代PHP中的每一行string
我有一个表单,允许用户上传文本文件或复制/粘贴到textarea文件的内容。 我可以很容易地区分两者,并把他们input的任何一个stringvariables,但我从哪里去?
我需要遍历string的每一行(最好不要担心在不同的机器上换行符),确保它只有一个标记(没有空格,制表符,逗号等),清理数据,然后生成一个SQL查询基于所有的线路。
我是一个相当优秀的程序员,所以我知道如何去做的一般想法,但是从我和PHP合作已经很长时间了,我觉得我正在寻找错误的东西,从而得到无用的信息。 我遇到的关键问题是我想逐行读取string的内容。 如果它是一个文件,这将是容易的。
我主要是在寻找有用的PHP函数,而不是如何做的algorithm。 有什么build议么?
preg_split
包含文本的variables,并遍历返回的数组:
foreach(preg_split("/((\r?\n)|(\r\n?))/", $subject) as $line){ // do stuff with $line }
我想提出一个更快的(和内存有效的)替代scheme: strtok
而不是preg_split
。
$separator = "\r\n"; $line = strtok($subject, $separator); while ($line !== false) { # do something with $line $line = strtok( $separator ); }
testing性能,我用一万七千行testing文件迭代了100次: preg_split
花了27.7秒,而strtok
花了1.4秒。
请注意,虽然$separator
被定义为"\r\n"
,但strtok
会分开任何一个字符 – 从PHP4.1.0开始,跳过空行/标记。
请参阅strtok手册条目: http : //php.net/strtok
如果你需要在不同的系统中处理换行符,你可以简单地使用PHP预定义常量PHP_EOL(http://php.net/manual/en/reserved.constants.php),并简单地使用explode来避免正则expression式引擎的开销。;
$lines = explode(PHP_EOL, $subject);
这是过分复杂和丑陋的,但在我看来这是一条路要走:
$fp = fopen("php://memory", 'r+'); fputs($fp, $data); rewind($fp); while($line = fgets($fp)){ // deal with $line } fclose($fp);
Kyril的答案是最好的,因为你需要能够在不同的机器上处理换行符。
“我主要是在寻找有用的PHP函数,而不是一个如何去做的algorithm,有什么build议吗?
我用了很多:
explode()可以用来把一个string拆分成一个数组,给定一个分隔符。
implode()是爆炸的对手,从数组回到string。
foreach(preg_split('~[\r\n]+~', $text) as $line){ if(empty($line) or ctype_space($line)) continue; // skip only spaces // if(!strlen($line = trim($line))) continue; // or trim by force and skip empty // $line is trimmed and nice here so use it }
^ 这是如何正确地断线 ,与Regexp
跨平台兼容:)
strtok
潜在的内存问题:
由于build议的解决scheme之一使用strtok
,不幸的是它没有指出潜在的内存问题(虽然它声称是内存有效率)。 根据手册使用strtok
,
请注意,只有第一次调用strtok使用string参数。 随后每次调用strtok只需要使用该标记, 因为它跟踪当前string中的位置。
这是通过将文件加载到内存中来实现的。 如果你正在使用大文件,你需要刷新它们,如果你已经完成循环的文件。
<?php function process($str) { $line = strtok($str, PHP_EOL); /*do something with the first line here...*/ while ($line !== FALSE) { // get the next line $line = strtok(PHP_EOL); /*do something with the rest of the lines here...*/ } //the bit that frees up memory strtok('', ''); }
如果你只关心物理文件(例如datamining):
根据手册 ,对于file upload部分,您可以使用file
命令:
//Create the array $lines = file( $some_file ); foreach ( $lines as $line ) { //do something here. }