1

Тема: Регулярные выражения

Всем доброго вечера, обращаюсь к вам с проблемой.
Собственно вот задача: есть строка, в ней попадаются конструкции типа:
{text}bla-bla-bla{text2}bla-bla-bla{text3}
Где bla-bla-bla - любая последовательность символов.
Задача: найти все эти конструкции и вывести. Я делаю это так:

preg_match_all('/\{text\s+([\w\.])*\}+([\w.])*\+\{text2\}+([\w.])*\+\{text3\}/i',$content,$matches);
for ($q=0; $q<=count($matches); $q++) {
echo $matches[$q]."<br>";
}

Но как всегда ничего не работает big_smile
Заранее спасибо за помощь)

2

Re: Регулярные выражения

preg_match_all('/\{text\}(.+)\{text2\}(.+)\{text3\}/i',$content,$matches);
foreach ($matches as $value) {
  print_r($value);
}

3 (изменено: Hase, 2013-06-15 11:56:56)

Re: Регулярные выражения

Спасибо за ответ, но этот скрипт странно работает...  При таком скрипте:

$content='{text}qwerty{text2}qwerty{text3}123456{text}asdfg{text2}asdfg{text3}123456{text}zxcvb{text2}zxcvb{text3}123456';
preg_match_all('/\{text\}(.+)\{text2\}(.+)\{text3\}/i',$content,$matches);
foreach ($matches as $value) {
  print_r($value);
}

Выводит следующее:

Array ( [0] => {text}qwerty{text2}qwerty{text3}123456{text}asdfg{text2}asdfg{text3}123456{text}zxcvb{text2}zxcvb{text3} ) 
Array ( [0] => qwerty{text2}qwerty{text3}123456{text}asdfg{text2}asdfg{text3}123456{text}zxcvb )
Array ( [0] => zxcvb )

А хотелось бы вот так:

Array ( [0] => {text}qwerty{text2}qwerty{text3}) 
Array ( [0] => {text}asdfg{text2}asdfg{text3} )
Array ( [0] => {text}zxcvb{text2}zxcvb{text3} )

4

Re: Регулярные выражения

Попробуйте так.

preg_match_all('/\{text\}(.+?)\{text2\}(.+?)\{text3\}/i',$content,$matches);

5

Re: Регулярные выражения

Hanut сказал:

Попробуйте так.

preg_match_all('/\{text\}(.+?)\{text2\}(.+?)\{text3\}/i',$content,$matches);

Уже лучше!

Array ( [0] => {text}qwerty{text2}qwerty{text3} [1] => {text}asdfg{text2}asdfg{text3} [2] => {text}zxcvb{text2}zxcvb{text3} ) 
Array ( [0] => qwerty [1] => asdfg [2] => zxcvb ) 
Array ( [0] => qwerty [1] => asdfg [2] => zxcvb )

Первый массив выводит то что нужно, но откуда берутся следующие 2?

6

Re: Регулярные выражения

Смотрите вывод массива, чтобы понять как происходит поиск.

print_r($matches);

7 (изменено: Hase, 2013-06-15 16:06:03)

Re: Регулярные выражения

Что-то я туплю smile

Array (
     [0] => Array ( 
          [0] => {text}qwerty{text2}qwerty{text3}
          [1] => {text}asdfg{text2}asdfg{text3} 
          [2] => {text}zxcvb{text2}zxcvb{text3} 
     ) 
     [1] => Array ( [0] => qwerty [1] => asdfg [2] => zxcvb ) 
     [2] => Array ( [0] => qwerty [1] => asdfg [2] => zxcvb ) 
) 

Array ( 
     [0] => Array ( 
          [0] => {text}qwerty{text2}qwerty{text3} 
          [1] => {text}asdfg{text2}asdfg{text3}
          [2] => {text}zxcvb{text2}zxcvb{text3} 
     ) 
     [1] => Array ( [0] => qwerty [1] => asdfg [2] => zxcvb )
     [2] => Array ( [0] => qwerty [1] => asdfg [2] => zxcvb ) 
) 

Array ( 
     [0] => Array ( 
          [0] => {text}qwerty{text2}qwerty{text3} 
          [1] => {text}asdfg{text2}asdfg{text3} 
          [2] => {text}zxcvb{text2}zxcvb{text3} 
     ) 
     [1] => Array ( [0] => qwerty [1] => asdfg  [2] => zxcvb ) 
     [2] => Array ( [0] => qwerty [1] => asdfg  [2] => zxcvb 
     )
)

Вот вывод, как вы сказали...
3 абсолютно одинаковых массива...

8

Re: Регулярные выражения

Hase сказал:

3 абсолютно одинаковых массива..

Значит вывод сделан три раза. Ошибки нет.

9

Re: Регулярные выражения

Получается чтобы работать с нужным мне массивом, в функции мне надо написать return $mathes[0]?

10

Re: Регулярные выражения

Три раза выводит, потому что print_r внутри foreach.

В зависимости от того какие данные нужны, такой массив и разбирайте.

Смотрите документацию. http://lv.php.net/manual/ru/pcre.pattern.php

11

Re: Регулярные выражения

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

12

Re: Регулярные выражения

Попробуйте так.

preg_match_all('/([^\}]*)\{text\}(.+?)\{text2\}(.+?)\{text3\}/i',$content,$matches);

13 (изменено: Hase, 2013-06-22 16:09:02)

Re: Регулярные выражения

Hanut сказал:

preg_match_all('/([^\}]*)\{text\}(.+?)\{text2\}(.+?)\{text3\}/i',$content,$matches);

Да,спасибо, в одном из подмассивов выводится то что надо)

14

Re: Регулярные выражения

Наверно не в тему, но все же, а можно обрабатывать строки как условие? Например, у меня имеется строка:

$line = "$config = TRUE"

А дальше нужно сделать что-то наподобие:

if($line) { } else { }

15

Re: Регулярные выражения

Смотрите документацию функции eval()

$line = eval("$config = TRUE");

16

Re: Регулярные выражения

Hanut сказал:

Смотрите документацию функции eval()

$line = eval("$config = TRUE");

Большое спасибо!

17

Re: Регулярные выражения

Хм... Что-то не получается...

echo $line;
$q = eval("$line;");
if($q) {
   echo "TRUE";
} else {
echo "NOT TRUE";
}

выводит:

70>1
NOT TRUE

18

Re: Регулярные выражения

Хотя, в мануале сказано, что лучше обойтись без этой функции, я лучше сделаю через case, выбор не очень большой будет. Все равно спасибо!

19

Re: Регулярные выражения

Так еще вопрос по этой теме: нужно отыскать все конструкции вида {{sometext}}, где sometext не равняется t1 t2 и t3. Я сделал так, но у меня все равно t1 t2 t3 входят в эту конструкцию...

preg_match_all('/\{{((?!t1)(?!t2)(?!t3))(.+?)\}}/i',$page,$matches,PREG_SET_ORDER)

20

Re: Регулярные выражения

И кстати, Вы раньше мне помогли с регулярным выражением:

Hanut сказал:

Попробуйте так.

preg_match_all('/([^\}]*)\{text\}(.+?)\{text2\}(.+?)\{text3\}/i',$content,$matches);

И я провел неправильный тест. Данный скрипт не присваивает переменной все до вхождения той структуры, а присваивает все после "}"

sad

21

Re: Регулярные выражения

Hase сказал:

нужно отыскать все конструкции вида {{sometext}}

Найдите все sometext и сравните их с t1 t2 и t3. Делать регулярное выражение с исключениями не всегда удобно.

Hase сказал:

И я провел неправильный тест. Данный скрипт не присваивает переменной все до вхождения той структуры, а присваивает все после "}"

Приведите пример. Не смог понять.

22 (изменено: Hase, 2013-07-04 13:46:24)

Re: Регулярные выражения

Hanut сказал:

Приведите пример. Не смог понять.

Вообще для начала: то что я делаю - мини парсер шаблонов. Он мне не столько для пользования, сколько для понимания сути работы регулярных выражений и самих шаблонизаторов (я помню Вы мне советовали не писать свой шаблонизатор в виду того, что это долго, но у меня времени куча, могу хоть 5 лет писать smile ) Поэтому вот код:

Сам класс шаблонизатора:

<?php
    Class Template {
        
        public $PAGE;
        public $HREF;
        public $DOCTYPE;
        public $META;
        public $SCRIPTS;
        public $CSS;
        public $tags_array = array();
        public $active_temp;
        
        function __construct() {
            if(isset($_COOCKIE['templates'])) {
                $this->active_temp = $_COOCKIE['templates'];
            } else {
                $this->active_temp = "default";
            }
            $this->tags_array = array(
                "{{USER_NAME}}" => $_SESSION['user_name'],
                "{{USER_id}}" => $_SESSION['user_id'],
                "{{USER_IMAGE}}" => "<img alt='{USER_ID}' src='users/{USER_ID}/images/avatar.jpeg' class='user_image'>",
                "{{HEAD}}" => file_get_contents(GLOBAL_TEMPLATE_DIR . $this->active_temp . "/head.tpl"),
                "{{AJAX}}" => file_get_contents(GLOBAL_TEMPLATE_DIR . $this->active_temp . "/ajax.script"),
                "{{LOGIN_FORM}}" => file_get_contents(GLOBAL_TEMPLATE_DIR . $this->active_temp . "/login.tpl"),
            );
        }
        
        private function findTags($page) {
            if(preg_match_all('/\{\{(.+?)\}\}/i',$page,$matches,PREG_SET_ORDER) != 0 ) {
                return true;
            } else {
                return false;
            }
        }
        
        private function parseTags($page) {
            $areTAGS = true;
            while($areTAGS == TRUE) {
                if(preg_match_all('/\{\{(?!if)(.+?)\}\}/i',$page,$matches,PREG_SET_ORDER) != 0 ) {
                    $page = strtr($page, $this->tags_array);
                } else {
                    $areTAGS = false;
                }
            }
            return $page;
        }
        
        private function findLogic($page) {
            if(preg_match_all('/\{\[if\s(.+?)\]\}(.+?)\{\[else\]\}(.+?)\{\[endif\]\}/i',$page,$matches,PREG_SET_ORDER) != 0) {
                return $matches;
            } else {
                return false;
            }
        }
        
        private function parseLogic($page,$logic) {
            $content = '';
            preg_match_all('/([^\}]*)\{\[if\s(.+?)\]\}(.+?)\{\[else\]\}(.+?)\{\[endif\]\}/i',$page,$matches,PREG_SET_ORDER);
            $content = $content . $matches[0][1];
            foreach ($logic as $value) {
                switch ($value[2]) {
                    case "LOGGEDIN":
                        if($VARS['LOGGEDIN']) {
                            $content = $content . $value[3];
                        } else {
                            $content = $content . $value[4];
                        }
                    break;
                    case "ADMIN":
                       if($VARS['ADMIN']) {
                            $content = $content . $value[3];
                        } else {
                            $content = $content . $value[4];
                        }
                    break;
                }
            }
            return $content;
        }
        
        public function parseTpl($page) {
            $begin = $this->get_real_time();
            $toParse = true;
            while($toParse) {
                $tags = $this->findTags($page);
                if($tags) {
                    $page = $this->parseTags($page);
                }
                $logic = $this->findLogic($page);
                if($logic) {
                    $page = $this->parseLogic($page,$logic);
                }
                if($tags == false && $logic == false) {
                    $toParse = false;
                }
            }
            $end = $this->get_real_time() - $begin;
            $page = "<!-- HPEngine --> \n" . $page . " \n<!-- Страница сгенерирована за $end секунд -->";
            return "$page";
        }
        
        private function set_in_place($content) {
            echo $content;
        }
        
        public function loadPage($ajax) {
            if($ajax) {
                $content = file_get_contents(GLOBAL_TEMPLATE_DIR . $this->active_temp . '/' . $this->HREF . '.tpl');
                $content = $this->parseTpl($content);
                $this->set_in_place($content);
            } else {
$CONTENT = <<<CONTENT
$this->DOCTYPE
<html>
<head>
$this->META
$this->SCRIPTS
{{HEAD}}
</head>
    <body>
        $this->PAGE
    </body>
</html>
CONTENT;
                $page = $this->parseTpl($CONTENT);
                echo $page;
            }
        }
        
        public function get_real_time() {
            list ( $seconds, $microSeconds ) = explode( ' ', microtime() );
            return (( float ) $seconds + ( float ) $microSeconds);
        }
        
    }
?>

Часть engine.php

<?php
    $MYSQL = new Mysql;
    $TEMPLATE = new Template;
    $PARSER = new Parser;
    $TEMPLATE->HREF = $page;
    $SCRIPTS = "<script type='text/javascript'>\nvar JavaScriptFilesList = {";
    $dir = ROOT_DIR . "engine/javascript";
    $SCRIPTS .= searchFiles($dir,'*.js');
    $dir = ROOT_DIR . "templates/" . $TEMPLATE->active_temp . "/javascript";
    $SCRIPTS .= searchFiles($dir,'*.js');
    $dir = ROOT_DIR . "templates/" . $TEMPLATE->active_temp . "/javascript/" . $TEMPLATE->HREF;
    $SCRIPTS .= searchFiles($dir,'*.js');
    $SCRIPTS = $SCRIPTS . "\n}\n";
    $CSS = "\nvar CSSFilesList = {";
    $dir = ROOT_DIR . "templates/" . $TEMPLATE->active_temp . "/css/" . $TEMPLATE->HREF;
    $CSS .= searchFiles($dir,'*.css');
    $dir = ROOT_DIR . "templates/" . $TEMPLATE->active_temp . "/css";
    $CSS .= searchFiles($dir,'*.css');
    $SCRIPTS .= $CSS;
    $SCRIPTS = $SCRIPTS . "\n}\n" . file_get_contents(GLOBAL_ENGINE_DIR . "javascript/global/dynamicLoad") . "\n</script>";
    $PAGECONTENT = file_get_contents(GLOBAL_TEMPLATE_DIR . $TEMPLATE->active_temp . '/' . $TEMPLATE->HREF . '.tpl');
    $TEMPLATE->PAGE = $PAGECONTENT;
    $TEMPLATE->SCRIPTS = $SCRIPTS;
?>

index.php (часть)

<?php
    $TEMLATE->HREF = 'admin'; // допустим
    $TEMPLATE->loadPage(false);
?>

Класс db и functions.php приводить смысла нет, так как там все понятно.

В коде класса есть функция parseLogic() Она состоит из 2х частей: 1) отбирает контент до начала логики, 2) парсит логику. Возьмем, к примеру, страницу входа в админпанель. Вот admin.tpl:

    <a href="http://www.haprog.com">
        <img alt="HAPROG" src="/templates/default/images/logo.png" class="logo">
    </a>
    <div class="block round">
        <fieldset>
            <legend class="block_header">
                Вход в админпанель
            </legend>
            <div class="container">
                <form id="admin_login">
                    <input type="text" placeholder="login" name="login" class="round"><br>
                    <input type="password" placeholder="mypassword" name="password" class="round"><br>
                    <button class="button" onclick="logMe(admin_login); return false;">Войти</button>
                </form>
            </div>
        </fieldset>
        <div id="preview">

        </div>
    </div>


{[if ADMIN]}text{[else]}text{[endif]}

В итоге, если страница должна быть такая:

<!-- HPEngine --> 
<!DOCTYPE>
<html>
<head>
<meta charset=>
<meta author=>
<script type='text/javascript'>
var JavaScriptFilesList = {
'ajax.js' : 'engine/javascript/',
'engine.js' : 'engine/javascript/',
'common.js' : 'templates/default/javascript/',
}

var CSSFilesList = {
'common.css' : 'templates/default/css/',
}
function dynamicLoad(filesToLoad) {
    var i = 0;
    var fileRef = new Array();
    var fName = new Array();
    for(var key in filesToLoad) {
        var fileType = key.substr(-2);
        var fileName = key;
        var fileSRC = filesToLoad[key];
        if(fileType=="js") {
            fileRef[i] = document.createElement('script');
            fileRef[i].setAttribute("type","text/javascript");
            fileRef[i].setAttribute("src", fileSRC + fileName);
            fName[i] = fileName;
        } else if(fileType=="ss") {
            fileRef[i]=document.createElement("link");
            fileRef[i].setAttribute("rel", "stylesheet");
            fileRef[i].setAttribute("type", "text/css");
            fileRef[i].setAttribute("href", fileSRC + fileName);
            fName[i] = fileName;
        }
        if (typeof fileRef[i]!="undefined") {
            document.getElementsByTagName("head")[0].appendChild(fileRef[i]);
        };
        i = i + 1;
    };
    for (i = 0; i<fileRef.length; i++) {
        setCallbacks(fileRef[i], fName[i]);
    };
}
function setCallbacks(fileRef, fName) {
    fileRef.onload = function() {
        console.log(fName + " loaded successfully");
        
    }
    fileRef.onerror = function() {
        console.log("Some error occurred with loading " +fName);
    };
}
dynamicLoad(CSSFilesList);
dynamicLoad(JavaScriptFilesList);
</script>
<!-- Вывод пользовательской части тега <HEAD> (например, скрипты с внешних ресурсов и скрипты не входящие в список файлов-->
</head>
    <body>
             
    <a href="http://www.haprog.com">
        <img alt="HAPROG" src="/templates/default/images/logo.png" class="logo">
    </a>
    <div class="block round">
        <fieldset>
            <legend class="block_header">
                Вход в админпанель
            </legend>
            <div class="container">
                <form id="admin_login">
                    <input type="text" placeholder="login" name="login" class="round"><br>
                    <input type="password" placeholder="mypassword" name="password" class="round"><br>
                    <button class="button" onclick="logMe(admin_login); return false;">Войти</button>
                </form>
            </div>
        </fieldset>
        <div id="preview">

        </div>
    </div>

text

    </body>
</html> 
<!-- Страница сгенерирована за 0.00069880485534668 секунд -->

Скрипт ее выводит такой:

<!-- HPEngine --> 

dynamicLoad(CSSFilesList);
dynamicLoad(JavaScriptFilesList);
</script>
<!-- Вывод пользовательской части тега <HEAD> (например, скрипты с внешних ресурсов и скрипты не входящие в список файлов-->
</head>
    <body>
        
    <a href="http://www.haprog.com">
        <img alt="HAPROG" src="/templates/default/images/logo.png" class="logo">
    </a>
    <div class="block round">
        <fieldset>
            <legend class="block_header">
                Вход в админпанель
            </legend>
            <div class="container">
                <form id="admin_login">
                    <input type="text" placeholder="login" name="login" class="round"><br>
                    <input type="password" placeholder="mypassword" name="password" class="round"><br>
                    <button class="button" onclick="logMe(admin_login); return false;">Войти</button>
                </form>
            </div>
        </fieldset>
        <div id="preview">

        </div>
    </div>


 
<!-- Страница сгенерирована за 0.013168096542358 секунд -->

Т.е. реглярное выражение вырезает все, что стоит до последней "}", и НЕ присваивает это переменной

23

Re: Регулярные выражения

Вы пытаетесь собрать строку с помощью конкатенации, обычно используют preg_replace, при этом надо обратить внимание на то, что текст внутри шаблона не должен содержать специальных символов самого шаблона, в данном случае это фигурные скобки. Решается проблема специальных символов с помощью переменных, то есть пишут не текст, а имя переменной, которой соответствует любая строка.

24

Re: Регулярные выражения

Спасибо за объяснение.

Hanut сказал:

Решается проблема специальных символов с помощью переменных, то есть пишут не текст, а имя переменной, которой соответствует любая строка.

Можете привести самый простой пример?)

25

Re: Регулярные выражения

Сожалею, но не смогу помочь. Сейчас нет достаточно времени.