迭代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. }