[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Коварный дуэт while и str_replace
FatCat
Нарвался...
Имеется какая-то строка текста. Да, получаем от парсера, ну да не суть; важно лишь, что размер текса не превышает нескольких килобайт.
Дальше текст чистится от мусора, и при чистке периодически процесс зацикливался.
Розыски нашли виновного:
while(stristr($w_p_word,"  "))$w_p_word = str_replace("  "," ",$w_p_word);

Ничего не понимаю. Как это в принципе может зацикливаться?



Спустя 9 минут, 52 секунды (31.08.2011 - 14:47) Nikitian написал(а):
А ничего, что в паре используются регистронезависимая и регистрозависимая функции? Понимаю, что для пробелов разницы нет, но как-то оно неправильно имхо. Может в этом и косяк.

Спустя 3 минуты, 17 секунд (31.08.2011 - 14:50) linker написал(а):
Каким образом была выявлена именно эта строка? И почему не регулярка?

Спустя 6 часов, 17 минут, 46 секунд (31.08.2011 - 21:08) FatCat написал(а):
Цитата (linker @ 31.08.2011 - 15:50)
Каким образом была выявлена именно эта строка?

$w_p_word = str_replace("  "," ",$w_p_word);
echo "01\n";
while(stristr($w_p_word," "))$w_p_word = str_replace(" "," ",$w_p_word);
echo "02\n";

После зацикливания последняя запись на странице "01".

Спустя 1 минута, 3 секунды (31.08.2011 - 21:09) FatCat написал(а):
Цитата (linker @ 31.08.2011 - 15:50)
почему не регулярка?

Банально потому, что плохо ими владею.

Спустя 16 минут, 30 секунд (31.08.2011 - 21:26) Игорь_Vasinsky написал(а):
FatCat
Цитата
Банально потому, что плохо ими владею.

убил.. старейшина... убил.

Цитата
while(stristr($w_p_word,"  "))$w_p_word = str_replace("  "," ",$w_p_word);


а зачем вообще зацикливать ....
$w_p_word = str_replace("  "," ",$w_p_word);

не справляется? или там символы табуляции?

можно так попробовать
$w_p_word = str_replace(array("  ", "   ", "    ", "     ")," ",$w_p_word);

от 2-5 пробелов превратит в 1.

Спустя 28 минут, 25 секунд (31.08.2011 - 21:54) Игорь_Vasinsky написал(а):
не уж то прав biggrin.gif

Спустя 11 минут, 46 секунд (31.08.2011 - 22:06) FatCat написал(а):
Цитата (Игорь_Vasinsky @ 31.08.2011 - 22:26)
зачем вообще зацикливать ....

Затем, что число пробелов может быть в несколько сотен.


Цитата (Игорь_Vasinsky @ 31.08.2011 - 22:26)
не справляется? или там символы табуляции?

Там раньше есть строка:
$w_p_word = str_replace(chr(9)," ",$w_p_word);

А так же в пробелы преобразуются все знаки препинания, все теги регуляркой преобразуются в пробелы.
То есть, из форматированного текста страницы делается массив слов через пробел, потом эксплодится по пробелу, уникализуется - и получается массив слов страницы.

Спустя 3 минуты, 15 секунд (31.08.2011 - 22:09) FatCat написал(а):
Цитата (Игорь_Vasinsky @ 31.08.2011 - 22:26)
убил

Нагрузочные они. На больших строках жрут ресурсы на пару порядков больше, чем substr и strpos.
Сейчас как раз предстоит большая работа переписать кучу регулярок на строковые операции, ибо ресурс ограничен, а посещаемость растет.

Спустя 1 минута, 37 секунд (31.08.2011 - 22:11) Игорь_Vasinsky написал(а):
... да.... с пентагона чтоль данные wink.gif

не справляется видимо цикл.. времени не хватает.

может глупость:

1. Получить текст
2. Записать в файл
3. Проделать это же... хз.

Спустя 4 минуты, 43 секунды (31.08.2011 - 22:16) Игорь_Vasinsky написал(а):
ну незнай... может в буфер всё, потом это циклить....

Спустя 11 минут, 37 секунд (31.08.2011 - 22:27) Nikitian написал(а):
Покаж текст, на котором ошибка, чтобы можно было потестить всякие варианты

Спустя 5 часов, 4 минуты, 47 секунд (1.09.2011 - 03:32) inpost написал(а):
FatCat
Кстати да, покажи какой-нибудь текстовый текст, попробуем коллективным разумом что-нибудь придумать.

Спустя 4 часа, 9 минут, 31 секунда (1.09.2011 - 07:41) kirik написал(а):
FatCat
Не логично тут использовать stristr. Тот же php.net советует использовать strpos() вместо.
Цитата (http://ca3.php.net/manual/en/function.strstr.php)
Note:
If you only want to determine if a particular needle occurs within haystack, use the faster and less memory intensive function strpos() instead.

Вообще попробуй так:
$txt = '123   tr  ddd        ss  d';
$txt = implode(' ', array_filter(explode(' ', $txt)));
echo $txt;

должно быть быстрее..

Спустя 2 дня, 16 часов, 52 минуты, 6 секунд (4.09.2011 - 00:34) FatCat написал(а):
Цитата (Nikitian @ 31.08.2011 - 23:27)
Покаж текст, на котором ошибка, чтобы можно было потестить всякие варианты

Текст получается при считывании страницы wordstat.yandex.ru методом fsockopen.
Может тысячи раз считаться без зацикливания, а может зациклиться в самый неожиданный момент.
Трафик при этом невелик, всего несколько килобайт.
В следующий раз эта же страница отработает без зацикливания.



Спустя 6 минут FatCat написал(а):
Эх, мне бы какую-то функцию для ограничения времени выполнения операции. Типа таймер на цикл, если больше заданного времени крутит, то чтобы прерывался...
Нет, таймер-то можно сделать, сейчас так и слепил грубо на коленке:
$start = time();
while(stristr($w_p_word," ") and ($start+2)>time())$w_p_word = str_replace(" "," ",$w_p_word);

А вот что-нибудь универсальное, чтобы одинаковым синтаксисом и fsockopen, и циклы, и любые друге операторы или блоки кода...

Спустя 26 минут, 27 секунд (4.09.2011 - 01:00) Nikitian написал(а):
попробуй stristr(} заменить на strstr(). Всё-таки меня терзают смутные сомнения...

Спустя 10 часов, 24 минуты, 33 секунды (4.09.2011 - 11:25) neadekvat написал(а):
$txt = preg_replace('#\s{2,}#', ' ', $txt);

Я бы не сказал, что она работает долго.

Спустя 1 день, 14 часов, 3 минуты, 8 секунд (6.09.2011 - 01:28) FatCat написал(а):
Цитата (Nikitian @ 4.09.2011 - 02:00)
Всё-таки меня терзают смутные сомнения...

Сделал цикл по длине строки:
for($i=0;$i<strlen($w_p_word);$i++)$w_p_word = str_replace("  "," ",$w_p_word);

И снова зациклился.
Или я что-то не понимаю: апач молотит на все выделенные ему 25% процессора и часами ничего не происходит на странице - это же зацикливание?

Спустя 7 минут, 33 секунды (6.09.2011 - 01:35) Игорь_Vasinsky написал(а):
Браузер вешает? может стоит разбить на куски - и работать с ними последовательно?

Спустя 6 часов, 6 минут, 43 секунды (6.09.2011 - 07:42) linker написал(а):
FatCat
Ну попросили жеж выложить пример текста, на котором происходит зацикливание. Не хочешь в паблик, кидай в личку.

Спустя 1 час, 3 минуты, 14 секунд (6.09.2011 - 08:45) kirik написал(а):
Цитата (FatCat @ 5.09.2011 - 18:28)
И снова зациклился.

Может таки не этот кусок?
Замени на регулярку, дабы исключить любую возможность "зацикливания". Наврятли регулярка усугубит ситуацию с ресурсами.. тем более твой for пересчитывает количество символов каждую итерацию - что не есть гуд.

Спустя 5 часов, 31 секунда (6.09.2011 - 13:46) FatCat написал(а):
Цитата (linker @ 6.09.2011 - 08:42)
попросили жеж выложить пример текста, на котором происходит зацикливание

Если бы я мог получить проблемный текст, наверное не было бы этого топика.
Парсятся тысячи страниц, и зацикливание происходит при сбое на сервере яндекса.


Цитата (kirik @ 6.09.2011 - 09:45)
Может таки не этот кусок?

Может быть не этот кусок.

Сейчас не могу проверить, яндекс перестал сбоить, и зацикливаний не происходит уже пару дней.


_____________
Бесплатному сыру в дырки не заглядывают...
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.