PHP « Как получить определённую строчку из текста?

Имея текст, состоящий из большого количества строк (до нескольких тысяч), необходимо получить определённую n-ую строку (пятую, десятую, сотую, сто вторую, тысячную или любую другую), строки соответсвенно разделяются сиволом n (rn).

Имеющиеся варианты:
1. Разбивать всё на массив, explode("n", $box), не слишком ли большой массив получится?
2. Выборка ^(.)+n(.)+n(.)+n(.)+n и в цикле добавляться (.)+n необходимое количество раз.

Какие есть варианты ещё? И какой наилучший?
Это долно работать на php и mysql, так что может можно как-то разделить эту работу между ними.

1 ответов


если текст в файле, то можно без explode:
$lines = file($file);
$line = $lines[400000];


Если у вас 100 000 строк - вы помрете, пока все сделаете.
Видел где-то классный финт. Смысл в том, чтобы используя возможности ОС снять заданную строчку из файла. Хоть 1ю, хоть 400 000 000-ую:

//...
//тут нужно сформировать путь к файлу в переменную $file.
//...
function getFileLine($file, $line) {
    return trim(exec("head -n $line $file | tail -n 1"));
}
Смысл сводится к тому, чтобы взять последнюю строчку из верхних n строк. Использует конвейеры. Не работает под Win-платформами. Метод платформозависимый, но на больших объемах - несравненно производительнее.
Если файла нет - то можно воcпользоваться таким способом:
<?php
    $tmpfname = tempnam("/tmp", "tmp_");     //создаем временный файл, получаем имя
    $temp = fopen($tmpfname, "w");           //открываем на запись
    fwrite($temp, "записываем кучу строк");
    $line = getFileLine($tmpfname,10000);    //считываем 10000 строку
    fclose($temp);                           //закрываем указатель
    unlink($tmpfname);                       // удаление файла
?>
Ну или считать переводы строки.

<?php
function readLine($file, $line_num, $delimiter="\n")
{
    /*** set the counter to one ***/
    $i = 1;

    /*** open the file for reading ***/
    $fp = fopen( $file, 'r' );

    /*** loop over the file pointer ***/
    while ( !feof ( $fp) )
    {
        /*** read the line into a buffer ***/
        $buffer = stream_get_line( $fp, 1024, $delimiter );
        /*** if we are at the right line number ***/
        if( $i == $line_num )
        {
            /*** return the line that is currently in the buffer ***/
            return $buffer;
        }
        /*** increment the line counter ***/
        $i++;
        /*** clear the buffer ***/
        $buffer = '';
    }
    return false;
}?>

А также
<?php

/*** the file to read ***/
$file = 'foo.txt';

       
/**
 *
 * Read a line number from a file
 *
 * @param    string    $file    The path to the file
 * @param    int    $line_num    The line number to read
 * @return    string    The line that is read
 *
 */

function readLine( $file, $line_number )
{
        /*** read the file into the iterator ***/
        $file_obj = new SplFileObject( $file );

        /*** seek to the line number ***/
        $file_obj->seek( $line_number );

        /*** return the current line ***/
        return $file_obj->current();
}

echo readLine( $file, 345678 );

?>

Отсюда: http://www.phpro.org/examples/Read-Line-From-File.html

Думаю при таких объемах данных наиболее оптимально будет вручную просматривать каждый символ в цикле и когда встречается \n увеличивать счетчик. Как счетчик будет равен номеру интересующей строки, останется вытащит кусок до следующего \n.
Ну вы поняли :)