Forum Webscript.Ru

Программирование => PHP => Тема начата: Covex от 23 Июня 2002, 23:05:21

Название: Регулярные. Паттерны хелп плиз.
Отправлено: Covex от 23 Июня 2002, 23:05:21
Помогите люди. Замкнуло меня чего-то. Не могу решить как   резануть со страницы все, что находиться между body> и вывести на экран.
Файл открыт, потом его немного  implode, а далее что preg_match , eregi? Как будет выгдядеть шаблон?
Все мои попытки кончались лишь выводом первого слова после .
Название: Регулярные. Паттерны хелп плиз.
Отправлено: Макс от 23 Июня 2002, 23:29:23
тут вобще-то можно и простые строковые функции использовать: 2 strpos() и один раз substr()

а если регекспы то примерно так:
preg_match("/(.*?)<\\/body>/im",$html_text, $matches);
print_r($matches);
(непроверял, но вроде правильно)
Название: Регулярные. Паттерны хелп плиз.
Отправлено: Меняздесьдавнонет от 23 Июня 2002, 23:58:12
во-первых, не implode file, а fread
А во-вторых, если ты пробовал, то и надо приводить пример, что именно ты пробовал. Чтобы тебе объяснили твою ошибку. На будущее.
Название: Регулярные. Паттерны хелп плиз.
Отправлено: Макс от 24 Июня 2002, 00:11:12
Цитировать
во-первых, не implode file, а fread

$html_text = implode("",file("a.html"));
Название: Регулярные. Паттерны хелп плиз.
Отправлено: Меняздесьдавнонет от 24 Июня 2002, 00:22:03
Правильно. Вот именно это делать не надо.
Очень глупо сначала считывать файл, бить его в массив, а потом снова джйнить из массива в одну строку.
То, что делается меньшим количеством операторов, далеко не всегда работает быстрее.
Название: Регулярные. Паттерны хелп плиз.
Отправлено: Макс от 24 Июня 2002, 00:30:11
Хммм. Честно говоря сам не тестил, но небезизвестный тебе Дима в http://php.spb.ru/php/speed.html#file писал что file() быстрее чем fopen/fread
Да и просто implode/file ИМХО УДОБНЕЕ чем fopen/fread
Название: Регулярные. Паттерны хелп плиз.
Отправлено: Меняздесьдавнонет от 24 Июня 2002, 00:50:53
Видеть в книге надо не фигу, а то, что там написано.
У Димы ни слова не написано про fread и считывание файла в строку. Там речь идет о массиве.
А я и без тестирования знаю, что оно будет быстрее, чем file.
Ну, а про удобство я уже писал. Нормальных программистов вообще мало, а  уж в РНР, на котором каждая кухарка берется писать - и совсем кот наплакал.
А с кухарки - какой спрос. Кончено она будет делать "как удобнее", а не как оптимальнее.
Название: Регулярные. Паттерны хелп плиз.
Отправлено: Меняздесьдавнонет от 24 Июня 2002, 00:59:21
Не поленился.
Протестировал.
$fd = fopen ($filename, "r");
$contents = fread ($fd, filesize ($filename));
fclose ($fd);
в 10 раз быстрее, чем
$contents=implode("",file($filename));
Файл 1 мег.
Название: Регулярные. Паттерны хелп плиз.
Отправлено: Макс от 24 Июня 2002, 02:08:31
Цитировать
Не поленился.
Протестировал.
$fd = fopen ($filename, "r");
$contents = fread ($fd, filesize ($filename));
fclose ($fd);
в 10 раз быстрее, чем
$contents=implode("",file($filename));
Файл 1 мег.

У меня под WIN98 PHP4.2.1 примеры:

error_reporting(E_ALL);
include("Timer.php");
$filename="php4ts.dll";

$_preg = new Benchmark_Timer;
$_preg->start();
$fd = fopen ($filename, "r");
$contents = fread ($fd, filesize ($filename));
fclose ($fd);
$_preg->stop();
echo $_preg->timeElapsed()."\\n";
?>

и

error_reporting(E_ALL);
include("Timer.php");
$filename="php4ts.dll";

$_ereg = new Benchmark_Timer;
$_ereg->start();
$contents=implode("",file($filename));
$_ereg->stop();
echo $_ereg->timeElapsed();
?>

Показывают результаты на уровне 0.06 - 0.09 оба варианта
php4ts.dll - 1мег
Название: Регулярные. Паттерны хелп плиз.
Отправлено: Меняздесьдавнонет от 24 Июня 2002, 03:35:56
Хех :-)
измеритель :-)
Во-первых, в php4ts.dll может вообще не быть переводов строк.
Во-вторых, делать надо в цикле.
а на таких малых цифрах погрешность очень велика.

Но класс городить ради 4 строчек - это круто...
У тебя небось накладные расходы на инициализацию таймерного класса забивают работу с файлом :-)))
Название: Регулярные. Паттерны хелп плиз.
Отправлено: Меняздесьдавнонет от 24 Июня 2002, 04:14:15
На php4ts.dll на 200 итерациях у меня тоже большая разница получилась. 2,3с против 12.

Кстати, насчет удобства. Если тебе так жалко операторов, то можешь свою функцию сделать и считывать файл вообще одним. Если уж у тебя на замер времени целый класс пришпандорен, то для чтения файла тем более можешь расстараться :-)
Название: Регулярные. Паттерны хелп плиз.
Отправлено: Меняздесьдавнонет от 24 Июня 2002, 04:19:54
Не, я правда по поводу таймерного класса не понимаю.
у меня весь замер времени занимает столько же символов, что у тебя - только вызов.
что там у тебя в классе такого понаписано-то, кроме
list($micro,$time)=explode(" ",microtime());
$stamp=$micro+$time;
list($micro,$time)=explode(" ",microtime());
echo ($micro+$time)-$stamp;
?
Не, я правда не понимаю...
Название: Регулярные. Паттерны хелп плиз.
Отправлено: Maniac от 24 Июня 2002, 11:50:52
Ладно, ребята, не грызитесь. Проделал независимое испытание.


function getmicrotime(){
    list($usec, $sec) = explode(" ",microtime());
    return ((float)$usec + (float)$sec);
    }

$time_start = getmicrotime();


for ($i=0; $i < 100; $i++)
{
$html_text = implode("",file("access3.log"));
}

$time_end = getmicrotime();
$time = $time_end - $time_start;

print "
Did implode 100 times in $time seconds";
$time_start = getmicrotime();
for ($i=0; $i < 100; $i++)
{
$file=fopen("./access3.log","r");
$html_text = fread($file,filesize("access3.log"));
fclose($file);
}

$time_end = getmicrotime();
$time = $time_end - $time_start;
print "
Did fread 100 times in $time seconds";
?>


Результаты:
Did implode 100 times in 141.09852898121 seconds
Did fread 100 times in 3.3001800775528 seconds
Название: Регулярные. Паттерны хелп плиз.
Отправлено: Макс от 24 Июня 2002, 13:01:40
Согласен, был неправ, вспылил. При размере текстового файла в 6 метров fread в 24 раза быстрее чем implode
Цитировать
$html_text = fread($file,filesize("access3.log"));
Насколько мне известно, данные функции filesize() кешируются php поэтому при следующих циклах данные браться будут из кеша. clearstatcashe() нужно делать (ИМХО) для более точного теста. Хотя даже в это млучае fread значительно быстрее на файлах большого размера.

Цитировать
Кстати, насчет удобства. Если тебе так жалко операторов, то можешь свою функцию сделать и считывать файл вообще одним.
Тоже мне нашел к чему придраться.
Удобно мне так и код более читабельный получается.
И класс уже готовый, самому писать ничего не нужно было.
Может ты еще скажешь, что и классы нельзя использовать?
Ведь они почти в 1.5 раза замедляют работу скриптов
Название: Регулярные. Паттерны хелп плиз.
Отправлено: Меняздесьдавнонет от 24 Июня 2002, 13:20:04
Значешь, я не буду говорить, что нельзя. Используй на здоровье :-)
Просто когда я хочу поесть супу, я беру ложку, а не экскаватор :-)

А дело действительно не в clearstatcache, а в накладных расходах на работу с массивами.
Название: Регулярные. Паттерны хелп плиз.
Отправлено: Covex от 24 Июня 2002, 18:43:06
Ребята! все очень хорошо, весь этот ..дешь, но только вот

if (is_uploaded_file($legend)) {
    $legend = file ($legend);
$legen = implode ("", $legend);
preg_match("/(.*?)<\\/body>/im",$legen, $matches);
echo "OK
".$matches[0];
echo (join(" ", $matches));
}

не хочет работать..... а так очень конкретно все обсудили ...  
Цитировать
тут вобще-то можно и простые строковые функции использовать: 2 strpos() и один раз substr()
вот это наверное правильнее всего будет...... насколько я понял они меньше тормозить будут . Спасибо.
Ну а все-таки как  с регами то...........
Название: Регулярные. Паттерны хелп плиз.
Отправлено: Covex от 24 Июня 2002, 18:51:08
Цитировать
Нормальных программистов вообще мало, а уж в РНР, на котором каждая кухарка берется писать - и совсем кот наплакал.
А с кухарки - какой спрос. Кончено она будет делать "как удобнее", а не как оптимальнее.

Англо-русский словарь:  chef - шеф-повар, главный повар
изд. "Сов. энциклопедия" М. - 1967
Название: Регулярные. Паттерны хелп плиз.
Отправлено: Меняздесьдавнонет от 24 Июня 2002, 19:03:55
Ну, ты-то даже и в кухарки не годишься, мой мальчик.
Уж самая тупая догадается из форума пример скоипровать, а тебе и это не удалось.
Название: Регулярные. Паттерны хелп плиз.
Отправлено: Макс от 24 Июня 2002, 19:15:04
Цитировать
не хочет работать.....
дык что именно не работает? Что в массиве $matches ?
что error_reporting(E_ALL) выдает?

"/(.*?)<\\/body>/im" - слеши правильно стоят?
- так и написано в файле или там ?
Название: Регулярные. Паттерны хелп плиз.
Отправлено: GotZfild от 24 Июня 2002, 20:32:18
Цитировать
"/(.*?)<\\/body>/im"

Только еще модификатор s нужно добавить, а m можно и убрать:
preg_match("/]*>(.*?)<\\/body>/is", $legen, $matches);
Название: Регулярные. Паттерны хелп плиз.
Отправлено: Covex от 24 Июня 2002, 22:20:11
GotZfild
Warning: Unknown modifier \'b\' in f:\\www\\teacher_func.php3 on line 123
это ответ на preg_match("/]*>(.*?)/is", $legen, $matches);
$matches - массив но пустой.......
Цитировать
error_reporting(E_ALL)
Unknown modifier \'b\' in ...
Undefined offset: 1 in....
Название: Регулярные. Паттерны хелп плиз.
Отправлено: GotZfild от 24 Июня 2002, 22:33:58
Косая черта вырезалась. Попробую еще раз:
preg_match("/]*>(.*?)<\\\\/body>/is", $legen, $matches);
Название: Регулярные. Паттерны хелп плиз.
Отправлено: Covex от 24 Июня 2002, 22:40:04
походу сработало!
Большое спа.
Название: Регулярные. Паттерны хелп плиз.
Отправлено: Covex от 24 Июня 2002, 22:46:08
но  сами остались....... можно их того......
Название: Регулярные. Паттерны хелп плиз.
Отправлено: Maniac от 25 Июня 2002, 10:44:58
Можно и их того.

$file=fopen("./index.htm","r");
$content=fread($file,filesize("./index.htm"));
print \'
\';
print "$content\\n";


if (preg_match_all(\'/(.*?)<\\/body>/si\',$content,$res,\'PREG_PATTERN_MATCH\'))
    print $res[1][0];
else print \'nothing matched\';
print \'
\';
?>
Прошу обратить внимание на:
1) у закрывающего тега перед / стоит \\. Что избавляет тебя от ошибок, которые выскакивали  (надеюсь, ты сам уже это понял)
2) модификатор регулярного выражения s, который означает, что вас не укачает (шутка). Который означает, что . - это любой символ ВКЛЮЧАЯ конец строки (без него, вообще говоря, работать будет не всегда)
3) содержимое между тегами в регулярном выражении взято в скобки, что позволяет обращаться к нему при помощи массива res[1].

В общем, RTFM (http://www.tuxedo.org/~esr/jargon/html/entry/RTFM.html) по адресу http://www.php.net/manual/en/function.preg-match-all.php .
Там даже примеры есть (и, кстати, некоторые из них - как вырезать содержимое тегов)