alhames.ru
Дано:
Имеется произвольный набор текста, размером не превышающим 100 Кб.
Задача:
Необходимо извлечь из текста все имэйлы и создать двумерный массив вида:
<?
//из "[email protected][email protected][email protected]..."  в:
$e_mail['login'][0]="petrov"//логин пользователя
$e_mail['domen'][0]="mail.ru"//почтовый домен
$e_mail['login'][1]="sidorov";
$e_mail['domen'][1]="yandex.ru";
$e_mail['login'][2]="ivanov";
// ... и т.д.
?>


Вопрос:
Какие методы в данном случае будут наиболее оптимальны?

@темы: Оптимизация, PHP

Комментарии
13.02.2008 в 00:25

 
что-нибудь типа

<?php

   
function get_emails($s)
   {
     
preg_match_all("#([\w][-\.\w]+)\@([-\.\w]+\.[a-z]{2,5})#i"$s$mPREG_PATTERN_ORDER);
      return array(
"login" => $m[1], "domain" => $m[2]);
   }

?>



? :)
13.02.2008 в 00:30

alhames.ru
La personne mystique текст большой (50-100 Кб) -не приведет ли предложенная функция к излишней нагрузки сервера?
13.02.2008 в 00:31

Будем же учиться хорошо мыслить - вот основной принцип морали (с) Паскаль
Хмм.. Вообще, вопрос интересный. Гонять регулярку по такому объему не факт что эффективно, хотя это, конечно, наиболее простой метод. Пара вальтернативных идей у меня есть, на надо тестировать что эффективнее. В принципе, все зависит от ситуации - где-то регулярка вполне допустима. Несколько вопросов:
1. какая предполагается нагрузка на скрипт (количество итераций в еденицу времени, максимальный объем текста за одну итерацию)
2. Версия php и apache
13.02.2008 в 00:37

 
alhames, вообще, основные потери мощности с регулярными - при инициализации, поэтому в разумных пределах они тем эффективнее, чем больший объем текста требуется обработать. А еще, стоит учесть, что написанная "регулярка" делает единственный проход по строке, тогда как практически любой парсинг с использованием строковых функций наверняка сделает больше прогонов ^^ Есть еще посимвольный анализ, но он эффективен только на низком уровне, а на PHP хорошо оптимизированные функции perl regular exprеssions, реализованные на Сях, явно должны быть быстрее :)
13.02.2008 в 00:47

alhames.ru
FVA требуется подобрать наиболее универсальную функцию, не зависящую от нагрузки, и уж тем более от настроек сервера.
Единственное, что надо учесть - это то, что большинство хостингов еще не поддерживают PHP 5, поэтому желательно ограничется ресурсами 4й версии.

La personne mystique я попробую протестировать скорость исполнения регулярки -завтра напишу.
А если использовать строковые функции -какой алгоритм?
13.02.2008 в 01:07

 
текст 1.25 Мб, содержащий 30'000 адресов, среднее значение за 20 прогонов
регулярные выражения - 1.42 сек
строковые функции - 1.67 сек

вот так использовал строковые функции (правда, тут есть ложные срабатывания ;) ):
<?php

   
function get_emails($s)
   {
     
$offset 0;
     
$len strlen($s);
     
$data = array();
      while ((
$pos strpos($s'@'$offset)) !== FALSE)
      {
         
$l 1;
         while ((
$p $pos $l) >= && (ctype_alnum($c $s[$p]) || $c == '-' || $c == '_' || $c == '.'))
            ++
$l;
         --
$l;
         
$r 1;
         while ((
$p $pos $r) <= $len && (ctype_alnum($c $s[$p]) || $c == '-' || $c == '_' || $c == '.'))
            ++
$r;
         --
$r;
         if (
$s[$pos $r] == ".") --$r;
         
$data[] = array("username" => substr($s$pos $l$l), "domain" => substr($s$pos 1$r));
         
$offset $pos $r;
      }
      return 
$data;
   }

?>

13.02.2008 в 02:17

Будем же учиться хорошо мыслить - вот основной принцип морали (с) Паскаль
Погонял различные тесты и понял одну интересную штуку - универсального алгоритма не получится - в разных ситуациях разные варианты эффективнее. Например, при работе с обычной html страничкой, с 20-30 адресами, регулярка дает 35-40 итераций в секунду, а строковые функции (реализация практически такая же как и у La personne mystique) - 2900-3100 итераций. При обработке мегабайтного файла наполненного одинаковыми адресами - дает 25-30, а строковые - 5-7. Ну и наконец самое интересное - при обработке файлов любого объема состоящих из разных адресов (адреса сгенерированы в цикле и каждый имеет вид md5(microtime())."@".md5(microtime())."com") - оба варианта дают практически одинаковые результаты, но строковые чуть-чуть впереди.

PS: Замеры по времени подтверждают описанные результаты.
13.02.2008 в 02:38

alhames.ru
FVA
Например, при работе с обычной html страничкой, с 20-30 адресами, регулярка дает 35-40 итераций в секунду, а строковые функции (реализация практически такая же как и у La personne mystique) - 2900-3100 итераций.
Имеется ввиду полный код html-странички? Мне собственно его обрабатывать и надо..
13.02.2008 в 02:39

Будем же учиться хорошо мыслить - вот основной принцип морали (с) Паскаль
alhames Ну да - я просто html код случайной страницы скопипастил и все. =)
13.02.2008 в 03:13

alhames.ru
FVA гм.. А почему такие колосальные различия в скорости не знаешь?
Да, кстать, а как ты измеряешь это кол-во итераций? А то мне это понятие непривычно -я привык в секундах все мерить..
13.02.2008 в 03:44

Будем же учиться хорошо мыслить - вот основной принцип морали (с) Паскаль
alhames Когда в тексте не очень много адресов, большие куски ненужного текста просто отбрасываются, путем выяснения позиции знака @, а регулярное выражение все-равно проходит по всему тексту. Итерации измеряю просто - делаю max_execution_time = 1 и пускаю функцию в бесконечном цикле.

UPD: на каждой итерации - echo ++$iterations;
13.02.2008 в 12:53

alhames.ru
"#([\w][-\.\w]+)\@([-\.\w]+\.[a-z]{2,5})#i"
:hmm:Как же я не люблю эти закорючки..:hmm:
Ладно, сейчас буду разбираться..

Кстати, хотел спросить, а что если написать скрипт автоматической генерации (и дегенерации:)) шаблонов регулярки? Востребованно будет? А то у меня мозги кипять от этих символов..

FVA интересная методика =) Только если функция выполняется больше секунды она не особо продуктивой становится - куда детальней в секундах будет :)
13.02.2008 в 13:10

Будем же учиться хорошо мыслить - вот основной принцип морали (с) Паскаль
alhames ничто не мешает дать скрипту 10, 20 и т.д. секунд на выполнение. Кроме того, я не говорю то это метод лучше или хуже - он несколько другой. При замере времени мы получаем результат выполнения функции 1 раз, а при подсчете итераций - результат многократного выполнения функции - то есть очень упрощенной имитации нагрузки на сервер. =)
13.02.2008 в 13:46

alhames.ru
FVA да я ниче против не имею =)
Мне нравицо =)
19.02.2008 в 21:00

Оптимизация - я понимаю под этим SEO... )) Надо, значит, пост сделать на тему SEO, чтобы не путались)
19.02.2008 в 22:08

alhames.ru
runawayboy нуу.. Оптимизации бывают разые =)
А тему SEO добавлю ;-)
19.02.2008 в 23:29

Пасибо) Обещаю на недельке соорудить первый пост=)

Расширенная форма

Редактировать

Подписаться на новые комментарии
Получать уведомления о новых комментариях на E-mail