Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Тексты > использование повтора внутри шаблона


Автор: z-END 10.6.2013, 12:50
Задача казалось бы простейшая - нужно получить названия всех переменных массива $array[XXX], которые находятся внутри комментариев в теле страницы. 

Код


<?php
$tpl='<html>
    <!--$array[first]-->
    <some tags>
        <!-- comments and data $array[values] -->
        <some_tags>
        <!-- comments and data $array[extra info] information about something else $array[info] -->
        </some_tags>
        <text_tag>
        $array[this_data_must_be_excluded]
        </text_tag>
    </some_tags>
    </html>
';

preg_match_all('/<!--(?:.*)\$array\[(.*)\](?:.*)-->/sU', $tpl, $results, PREG_PATTERN_ORDER);
var_dump($results);



Цитата

array
  0 => 
    array
      0 => string '<!--$array[first]-->' (length=20)
      1 => string '<!-- comments and data $array[values] -->' (length=41)
      2 => string '<!-- comments and data $array[extra info] information about something else $array[info] -->' (length=91)
  1 => 
    array
      0 => string 'first' (length=5)
      1 => string 'values' (length=6)
      2 => string 'extra info' (length=10)

но, в таком варианте получается только первое значение -  $array[extra_info] находит, а $array[info] уже нет... а как добавить повторение  что-то не соображу.. как быть? )


Автор: Gromdron 13.6.2013, 15:08
А вы попробуйте сначала отсеивать нужные строки по принципу <!--(.*)--> а потом НЕ жадной регуляркой искать $array\[(.*)\]

Этот ответ добавлен с нового Винграда - http://ru.vingrad.com//object-id51b5a18c6ccc19322d000002#findElement_E7045_51b9b6516ccc19673c000b6a_0

Автор: z-END 13.6.2013, 16:10
Gromdron,  уже была мысль обычным substr сначала вытащить все что внутри комментариев , и потом регуляркой уже по отфильтрованному тексту выдергивать $array... но как-то  не научно выглядит)  

Автор: krypt3r 14.6.2013, 07:03
Код

$values = array ();
preg_match_all ('/<!--(.*?)-->/s', $tpl, $m);
foreach ($m[1] as $cline)
{
    if (preg_match_all ('/\$array\[(.*?)\]/', $cline, $matches))
    {
        //print_r ($matches[1]);
        foreach ($matches[1] as $m_m)
        {
            $values[] = $m_m;
        }
    }
}
print_r ($values);

Код

Array
(
    [0] => first
    [1] => values
    [2] => extra info
    [3] => info
)

Или разбираться с рекурсивными RE

Автор: z-END 14.6.2013, 11:17
как по мне - две регулярки это перебор, по этому пока решил так:
Код

                $open = "<!--";
                $close = "-->";
                $found = strpos ($tpl, $open);
                $restpl = '';
                while ($found!==false) {
                    $last = strpos($tpl, $close, $found);
                    if (!$last) {
                           $found = false;
                           continue;
                    }
                    $restpl.= " ".substr ($tpl, $found+strlen($open), $last-$found-strlen ($close)-1);
                    $found = strpos ($tpl, $open, $last);
                }
                preg_match_all ('/\$array\[(.*)\]/sU', $restpl, $result, PREG_PATTERN_ORDER);

но мои сомнения в бесполезности регулярок  укрепились ))

Автор: Gromdron 14.6.2013, 23:17
Вообще это можно сделать регулярным выражением, но решение этой задачи сводиться к решению парсингу html страницы (которое до конца пока никто не решил), самое просто решение - получить все закомментированные строки после чего уже отобрать в них.

А если пробовать регуляркой то условия должны быть сложнее, типа: Перед выражением должно стоять <!-- на любых позициях и не должно стоять -->, при этом если стоит --> то открывающих <!-- должно быть на 1 больше... в общем длинное и запутанное условие получается. ИМХО проще получить строки и уже в них найти.

P.S. хотя можно попробовать считать теги <!-- и --> и генерировать ее находу, но это уже темная сторона кода, да и профита никакого не будет :)

Этот ответ добавлен с нового Винграда - http://ru.vingrad.com//object-id51b5a18c6ccc19322d000002#findElement_E7045_51bb7a5c6ccc193e3f000480_0

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)