Итерация по каждой строке в строке PHP
У меня есть форма, которая позволяет пользователю загрузить текстовый файл или скопировать/вставить содержимое файла в текстовое поле. Я могу легко различать их и помещать тот, который они ввели в строковую переменную, но куда я иду оттуда?
Мне нужно перебирать каждую строку строки (желательно не беспокоясь о новых строках на разных машинах), убедитесь, что она имеет ровно один токен (без пробелов, вкладок, запятых и т. д.), санировать данные, а затем генерировать SQL-запрос, основанный на всех строках.
Я довольно хороший программист, поэтому я знаю общую идею о том, как это сделать, но прошло так много времени с тех пор, как я работал с PHP, что я чувствую, что ищу неправильные вещи и, таким образом, придумываю бесполезную информацию. Ключевая проблема, с которой я сталкиваюсь, заключается в том, что я хочу прочитать содержимое строки построчно. Если бы это был файл, это было бы легко.
Я в основном ищу полезные функции PHP, а не алгоритм как это сделать оно. Есть предложения?
7 ответов:
preg_split
переменная, содержащая текст, и повторите над возвращенным массивом:foreach(preg_split("/((\r?\n)|(\r\n?))/", $subject) as $line){ // do stuff with $line }
Я хотел бы предложить значительно более быстрая (и эффективная память) альтернатива:
strtok
, а неpreg_split
.$separator = "\r\n"; $line = strtok($subject, $separator); while ($line !== false) { # do something with $line $line = strtok( $separator ); }
тестируя производительность, я повторил 100 раз над тестовым файлом с 17 тысячами строк:
preg_split
заняло 27,7 секунды, тогда как 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, чтобы избежать накладных расходов механизма регулярных выражений.
$lines = explode(PHP_EOL, $subject);
Это слишком сложно и некрасиво, но на мой взгляд это путь:
$fp = fopen("php://memory", 'r+'); fputs($fp, $data); rewind($fp); while($line = fgets($fp)){ // deal with $line } fclose($fp);
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
:)
ответ Кирилла лучше всего, учитывая, что вам нужно иметь возможность обрабатывать новые строки на разных машинах.
" Я в основном ищу полезные функции PHP, а не алгоритм для того, как сделать его. Есть предложения?"
Я использую их много:
- explode () может использоваться для разбиения строки на массив, учитывая один разделитель.
- implode() является аналогом explode, чтобы перейти от массива обратно к строка.
потенциальные проблемы с памятью с
strtok
:так как одно из предложенных решений использует
strtok
, к сожалению, он не указывает на потенциальную проблему с памятью (хотя он утверждает, чтобы быть эффективными памяти). При использованииstrtok
по данным руководство, the:обратите внимание, что только первый вызов strtok использует строковый аргумент. Каждый последующий вызов strtok нуждается только в маркере для использования,как это отслеживает, где он находится в текущая строка.
она делает это путем загрузки файла в память. если вы используете большие файлы, вам нужно очистить их, если вы закончили цикл через файл.
<?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
команда://Create the array $lines = file( $some_file ); foreach ( $lines as $line ) { //do something here. }