За последние 24 часа нас посетили 18564 программиста и 1631 робот. Сейчас ищет 1101 программист ...

Помогите с регулярными выражение

Тема в разделе "Регулярные выражения", создана пользователем heller, 28 май 2014.

  1. heller

    heller Новичок

    С нами с:
    17 май 2014
    Сообщения:
    4
    Симпатии:
    0
    Доброго времени суток.
    У меня есть некий файл с информацией

    Код (Text):
    1. <?xml version="1.0" encoding="utf-8" ?>
    2. <feed xmlns="http://www.w3.org/2005/Atom" xml:base="http://rutracker.org/forum/">
    3. <title>RPG</title>
    4. <updated>2014-05-28T13:40:01+00:00</updated>
    5. <id>tag:rto.feed,2000:/f/52</id>
    6. <link href="viewforum.php?f=52" />
    7. <entry>
    8.     <title><![CDATA[Final Fantasy III [L] [ENG|Multi5 / ENG] (2014) (1.0) [639 MB]]]></title>
    9.     <author>
    10.         <name>Rhadamanthus</name>
    11.     </author>
    12.     <updated>2014-05-27T19:05:05+00:00</updated>
    13.     <id>tag:rto.feed,2014-05-27:/t/4749147</id>
    14.     <link href="viewtopic.php?t=4749147" />
    Я с помощью регулярных выражений хочу выдрать из него все содержание тега <title>. Я написал скрипт
    Код (Text):
    1. preg_match_all("/title>[^>]+>/",$content,$title);
    Но, вместо того, чтобы в массив занести данные из всех тегов <titile> на странице, он заносит результат только с первой пары тегов. Т.Е. на выходе я получаю только
    Код (Text):
    1. Array ( [0] => Array ( [0] => title>RPG
    А далее массив пуст.
     
  2. ctaciv

    ctaciv Новичок

    С нами с:
    29 май 2014
    Сообщения:
    2
    Симпатии:
    0
    пробуй не регулярными, а для начала file_get_xml()
    потом делаешь DOM объект и из него уже как с JS работаешь.
     
  3. runcore

    runcore Старожил

    С нами с:
    12 окт 2012
    Сообщения:
    3.625
    Симпатии:
    158
    Это что за чудо функция? ))
     
  4. romach

    romach Старожил

    С нами с:
    26 окт 2013
    Сообщения:
    2.904
    Симпатии:
    719
  5. YSandro

    YSandro Старожил

    С нами с:
    7 апр 2011
    Сообщения:
    2.523
    Симпатии:
    2
    Странно. У меня больше выводит, только не правильно.
    А так?
    Код (PHP):
    1. $reg = '#<title>(.*)</title>#';
    2. preg_match_all($reg, $content, $title);
    3. var_dump($title); 
    Грубо, но должно работать. В $title[1] массив, в котором все тайтлы.
     
  6. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.770
    Адрес:
    :сердА
    Это называется XML.
    SimpleXML в помощь.

    Кто ж регулярками XMLы читает....е-мое.

    Добавлено спустя 1 минуту 45 секунд:
    Опять костыли. Да что с тобой?

    Добавлено спустя 4 минуты:
    Код (Text):
    1. $data = new SimpleXMLElement($переменная_с_содержимым_файла);
    2. //Либо:
    3. $data = simplexml_load_file($переменная_с_путем_к_файлу);
    4.  
    5. vardump($data->title);
    А еще лучше просто vardump($data); и кури структуру, что да как. Заодно почитай про xpath.
     
  7. YSandro

    YSandro Старожил

    С нами с:
    7 апр 2011
    Сообщения:
    2.523
    Симпатии:
    2
    Сам ты костыль, скунс. Это решение с регуляркой, как и хотел ТС.
     
  8. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.770
    Адрес:
    :сердА
    [​IMG]

    -Ребят, хочу зуб выдернуть пациенту. Помогите сделать это через жопу, а то по-другому я не знаю пока как!
    -Во, берешь знач расширитель диаметром больше твоей руки в локте и...
    -Блин, Исандро, опять костыли, ТС, попробуй через рот, удобнее, быстрее, проще.
    -Сам ты костыль, скунс. Это решение через жопу, как и хотел ТС.
     
  9. YSandro

    YSandro Старожил

    С нами с:
    7 апр 2011
    Сообщения:
    2.523
    Симпатии:
    2
    Не за чем парсить весь XML документ и выстраивать DOM в памяти, чтобы достать лишь одни тайтлы.
    http://habrahabr.ru/post/171667/
     
  10. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.770
    Адрес:
    :сердА
    1) Если xmlка не весит 10 метров, то не много-то в память и уйдет.
    2) Вангую, не ради только тайтлов ТС затеял это дело, просто решил спросить как сделать что-то одно, а там остальное по аналогии сам сделает.
    3) Если xmlka весит таки 10 метров, то, боюсь, регулярка может выйти накладнее, чем интерпретация в объект.
    4) xpath.
     
  11. YSandro

    YSandro Старожил

    С нами с:
    7 апр 2011
    Сообщения:
    2.523
    Симпатии:
    2
    Выбрать все символы между <title> и </title>, как и между другими тегами, всяко быстрей и менее накладней по ресурсам, чем полный парсинг с выстраиванием структуры, а потом ещё разбор результата XPath.
    А тут одна регулярка и -
    Ибо задача всего лишь
     
  12. YSandro

    YSandro Старожил

    С нами с:
    7 апр 2011
    Сообщения:
    2.523
    Симпатии:
    2
    Хе. Если вообще не хочется загружать файл в память
    Код (PHP):
    1. <?php
    2. header('Content-Type: text/plain');
    3. $searchTag = 'title';
    4. $titles = array();
    5. $titleN = 0;
    6.  
    7. $file = fopen('xml.xml', 'r');
    8. if($file !== false){
    9.     $tstart = microtime(true);
    10.     while(!feof($file)){
    11.         $s = fread($file, 1);
    12.         if($s == '<'){
    13.             $s2 = fread($file, 5);
    14.             if($s2 == $searchTag){
    15.                 $s3 = fread($file, 1);// >
    16.                 
    17.                 $stop = false;
    18.                 while(!feof($file) && !$stop){
    19.                     $s4 = fread($file, 1);
    20.                     if($s4 == '<'){
    21.                         $s5 = fread($file, 1);
    22.                         if($s5 == '/'){
    23.                             $s6 = fread($file, 5);
    24.                             if($s6 == $searchTag){
    25.                                 $stop = true;
    26.                                 $titleN ++;
    27.                             }
    28.                         }else{
    29.                             $s4 .= $s5;
    30.                         }
    31.                     }
    32.                     
    33.                     if(!$stop){
    34.                         if(isset($titles[$titleN])){
    35.                             $titles[$titleN] .= $s4;
    36.                         }else{
    37.                             $titles[$titleN] = $s4;
    38.                         }
    39.                     }
    40.                 }
    41.                 
    42.                 //echo "yes!\n";
    43.             }
    44.         }
    45.     }
    46.     $tend = microtime(true);
    47.     echo number_format($tend-$tstart,'4',',','').' sec. ';
    48.     fclose($file);
    49. }
    50.  
    51. var_dump($titles); 
    Так память вообще минимально ест. Но очень медленно. На любителя так сказать.
     
  13. YSandro

    YSandro Старожил

    С нами с:
    7 апр 2011
    Сообщения:
    2.523
    Симпатии:
    2
    Вот в 2-3 раза медленней вариант, чем с регулярками, но не загружающий файл в память
    Код (PHP):
    1. $tagStart = '<title>';
    2. $tagStartLen = strlen($tagStart);
    3. $tagEnd = '</title>';
    4. $titles = array();
    5. $titleN = 0;
    6. define('StateSearch', 1);
    7. define('StateTagStart', 2);
    8. $state = StateSearch;
    9.  
    10. $file = fopen('xml.xml', 'r');
    11. if($file !== false){
    12.     $tstart = microtime(true);
    13.     while(!feof($file)){
    14.         $line = fgets($file);
    15.         switch($state){
    16.             case StateSearch:
    17.                 if(($pos1 = strpos($line, $tagStart)) !== false){
    18.                     $state = StateTagStart;// нашли тег, проходим дальше
    19.                     $line = mb_substr($line, $pos1 + $tagStartLen);// отстригли начало строки с тегом
    20.                 }else{
    21.                     break;
    22.                 }
    23.  
    24.             case StateTagStart:
    25.                 if(($pos2 = strpos($line, $tagEnd)) !== false){// нашли закрывающий тег
    26.                     $line = mb_substr($line, 0, $pos2);
    27.                     if(isset($titles[$titleN])){
    28.                         $titles[$titleN] .= $line;
    29.                     }else{
    30.                         $titles[$titleN] = $line;
    31.                     }
    32.                     $titleN ++;
    33.                     $state = StateSearch;
    34.                     
    35.                 }else{// не нашли конец. ждать до следующей строки
    36.                     if(isset($titles[$titleN])){
    37.                         $titles[$titleN] .= rtrim($line);
    38.                     }else{
    39.                         $titles[$titleN] = rtrim($line);
    40.                     }
    41.                 }
    42.                 break;
    43.         }
    44.     }
    45.         
    46.     $tend = microtime(true);
    47.     echo number_format($tend-$tstart,'4',',','').' sec. ';
    48.     fclose($file);
    49. }
    50. echo 'count($titles):',count($titles), "\n"; 
    XML в 12.3 Mb обрабатывает за 0.61 сек.

    Вариант с регуляркой обрабатывает за 0.21 сек.

    Вариант с simplexml_load_file только загружает файл за 0.62 сек. Сколько добавят XPath и последующий разбор - пусть Fell-x27 разбирается.
     
  14. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.770
    Адрес:
    :сердА
    Загони своего сферического коня обратно в вакуумное стойло.

    ТС живет в реальном мире и парсит ATOM, это аналог RSSки. Ты хоть гигабайтовые файлы обсчитывай, но тут-то речь идет о n-килобайтовой простынке.
     
  15. YSandro

    YSandro Старожил

    С нами с:
    7 апр 2011
    Сообщения:
    2.523
    Симпатии:
    2
    это ответ на твоё же бредположение