[help] удаление строк которые не соответсвуют длине

Статус
В этой теме нельзя размещать новые ответы.

blackspy

Постоялец
Регистрация
11 Мар 2007
Сообщения
426
Реакции
144
Необходимо из файла удалить строки которые меньше 10 символов.
 
Тогда не {0,10} а {0,9}.
Кроме того для данного решения есть ограничение связанное с размером выделяемой php процессу оперативки, так как весь файл читается предварительно в память.

Впрочем вполне можно тупо в цикле прочесть построчно файл с перезаписью в другой только строк длиной меньше 10 символов.
 
Тут тебе в помощь регулярные выражения

$text=preg_replace("(\b((\S{0,10}))\b)", " ",$text );
Пробел там точно лишний, думаю, не нужно объяснять почему :) :
$text=preg_replace("(\b((\S{0,9}))\b)", "",$text );
 
Вы хоть сами это выражение проверяли? Оно удалит все слова, с длинной меньше 10 символов.
Правильное выражение вот:
$text=preg_replace("/^.{0,9}$[\r\n]*/m", "",$text );
 
В общем то с замечаниями согласен.


Хотя считаю что малость придираетесь.
Писал навскидку.

Не проверяя. Просто задава общую идею.
 
Не придираюсь:) Но если разложить регулярку по косточкам, то:
\b- означает начало и конец слова, а не строки
((\S{0,10})) -зачем сохраняюще скобки, тем более двойные, тем более здесь вообще не надо скобок.
(\b((\S{0,10}))\b) - \S означает не пробел. В строке не может быть пробелов?
Ну и надо захватить символы конца строки, иначе и правильное выражение просто очистит строку от символов, а не удалит, у меня [\r\n]*
 
Эту задачу можно решить без всяких регулярок и будет в несколько раз быстрее.

Простой пример
PHP:
<?php

function test1() {
    $a[] = 'dgdfhfjfdjfjkfk';
    $a[] = '123455';
    $a[] = '12345678901';
    $a[] = 'fdhfh';
    
    for($i = 0; $i < count($a); ++$i)
        $a[$i]=preg_replace("/^.{0,9}$[\r\n]*/m", "",$a[$i] );
}

function test2() {
    $a[] = 'dgdfhfjfdjfjkfk';
    $a[] = '123455';
    $a[] = '12345678901';
    $a[] = 'fdhfh';
    
    $k = count($a);
    for($i = 0; $i <= $k; ++$i)
        if(!isset($a[$i][10]))
           unset($a[$i]);
}

test1();
test2();

?>
При 10 запусках профайлер показал, что функция test2() выполняется в 4-6 раз быстрее функции test1().

Приспособить к задаче ТС - делов на 1 минуту.
 
Без регулярок, ясен перец может быстрей работать, но дольше в разработке. ТС как я понял нужен простой рабочий вариант, не обязательно PHP Для просмотра ссылки Войди или Зарегистрируйся

З.Ы. Регулярку надо применять ко всему тексту, а не разбивать сначала на массив и проходить циклом, в котором надо просто проверить длинну элемента.
test1() работает не правильно- просто заменяет элементы массива со строкой длинной<10 пустой строкой. Соответственно сравнение не корректно.

З.Ы.2
Итого будет 3 строки
PHP:
<?php
$text = file_get_contents('file.txt');  
$text = preg_replace('/^.{0,9}$[\r\n]*/m', "", $text);   
file_put_contents('file.txt', $text);  
?>
 
З.Ы. Регулярку надо применять ко всему тексту, а не разбивать сначала на массив и проходить циклом, в котором надо просто проверить длинну элемента.
Массив показан только для наглядности - никто не запрещает читать из файла построчно (хотя можно прочитать файл сразу же в массив), проверять как в test2() и по результатам либо выкидывать строку либо оставлять.

test.txt
Код:
dgdfhfjfdjfjkfk
123455
12345678901
qwertyui7
PHP:
<?php

function test1() {
    $text = file_get_contents('test.txt');
    $text = preg_replace('/^.{0,9}$[\r\n]*/m', "", $text);
    file_put_contents('file.txt', $text);
}

function test2() {
    $a = file('test.txt');

    $k = count($a);
    for($i = 0; $i < $k; ++$i) {

        if(!isset($a[$i][10]))
           unset($a[$i]);
        else
           $a[$i] = str_replace("\r\n", '', $a[$i]);
    }

    file_put_contents('file1.txt', implode("\r\n", $a));
}

for($i = 0; $i < 10; ++$i)
    test1();

for($i = 0; $i < 10; ++$i)
    test2();

?>
test1() - 66.83 мсек
test2() - 49.12 мсек

Чем test.txt будет больше, тем разница во времени будет существеннее.

PS Если файл большой, то лучше читать построчно.
 
Статус
В этой теме нельзя размещать новые ответы.
Назад
Сверху