Есть шаблоны страниц, хранящихся в файлах (или в БД - не суть важно), в которых встречаются определенного вида выражения для подстановки.
Заранее неизвестно ни какие выражения будут в шаблоне, ни сами выражения. Известно лишь что выражения могут повторяться (не обязательно подряд) и включаться одно в другое и соответствуют шаблону #\{\{[a-z]{1}[a-z0-9_:-]+[a-z0-9]{1}\}\}#i (т.е. в двойных фигурный скобках заключено слово начинающееся с буквы; в середине может содержать буквы, цифры, двоеточие, подчеркивание или тире; обязательно должно заканчиваться буквой или цифрой).
Как модифицировать этот шаблон что бы он не возвращал вместо {{bla:{{blin}}}} такое {{bla:{{blin}} ?
Вопрос в том как получить это слово (хотя бы в фигурных скобках) ?
А потом заменить найденное выражение (после распознавания слова и получения / генерации замены для него) ?
PS гугл не помог в данном вопросе помогите хотя бы вы...
подскажите хотя бы функции с помощью которых это можно реализовать ?
Спустя 1 час, 31 минута, 29 секунд (18.01.2012 - 22:16) killer8080 написал(а):
Спустя 20 минут, 28 секунд (18.01.2012 - 22:37) asokol написал(а):
explode('{{', ...);
А умение пользоваться регулярными выражениями в любом случае не помешает.
А умение пользоваться регулярными выражениями в любом случае не помешает.
Спустя 1 минута, 35 секунд (18.01.2012 - 22:38) Winston написал(а):
Цитата (TinK @ 18.01.2012 - 19:45) |
Как модифицировать этот шаблон что бы он не возвращал вместо {{bla:{{blin}}}} такое {{bla:{{blin}} ? |
А какое он должен возвращать?
Спустя 9 часов, 54 минуты, 48 секунд (19.01.2012 - 08:33) TinK написал(а):
Цитата (killer8080 @ 18.01.2012 - 19:16) |
TinK копай preg_replace() и preg_ replace_ callback() и учи регулярки |
Спасибо за функции.
На счет регулировок - подскажите нормальный учебник (статьи я уже читал - не очень понятно по моей задаче).
Цитата (Winston @ 18.01.2012 - 19:38) | ||
А какое он должен возвращать? |
Должно возвращаться {{bla:{{blin}}}} или {{bla_{{blin_0}}}} - в общем, вместе с подвыражением,
а не {{bla:{{blin}} или {{bla_{{blin_0}} - где теряются закрывающие скобки выражения.
Спустя 6 минут, 50 секунд (19.01.2012 - 08:40) Игорь_Vasinsky написал(а):
preg_replace("#\}{4}#", "}}", $tpl);
или
str_replace("}}}}", "}}", $tpl);
Спустя 6 минут, 44 секунды (19.01.2012 - 08:47) TinK написал(а):
Цитата (Игорь_Vasinsky @ 19.01.2012 - 05:40) |
preg_replace("#\}{4}#", "}}", $tpl);или str_replace("}}}}", "}}", $tpl); |
Спасибо конечно Игорь_Vasinsky, но потом же нужно из выражения (после отбрасывания скобок в начале и в конце) получить подвыражение и заменить его (перед разбором самого выражения), с такой заменой это уже окажется невыполнимо т.к. закрывающихся скобок подвыражения уже не будет...
Спустя 6 минут, 32 секунды (19.01.2012 - 08:53) TinK написал(а):
Цитата (TinK @ 18.01.2012 - 17:45) |
Как модифицировать этот шаблон что бы он не возвращал вместо {{bla:{{blin}}}} такое {{bla:{{blin}} ? |
С регуляркой кажется понял как надо: #\{\{[a-z]{1}[a-z0-9_:\{\}-]+[a-z0-9]{1}\}\}#i
Не очень красиво, но сейчас попробую... надеюсь regexp переварит...
Спустя 3 минуты, 6 секунд (19.01.2012 - 08:56) Игорь_Vasinsky написал(а):
давайка на живом примере - а то первый пост вообще не ясен
Спустя 13 минут, 51 секунда (19.01.2012 - 09:10) TinK написал(а):
Ну скажем такой мини шаблон:
<!doctype html>
<html>
<head>
<meta charset="utf-8" content="text/html; charset=UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>{{page_title}}</title>
<base href="{{web_basepath}}" />
</head>
<body id="{{page_bodyid}}">
{{web_blank:{{page_bodyid}}}}
</body>
</html>
Спустя 29 минут, 1 секунда (19.01.2012 - 09:39) asokol написал(а):
TinK, попробуйте использовать explode. Я не проверял, но по идее explode будет работать быстрее, меньше нагрузка на процессор, к тому же проще, на мой взгляд, определять ошибки подстановки. Если не совсем понятно, каким образом пользоваться, то я постараюсь объяснить.
Или же эта задача решается исключительно в целях изучения регулярных выражений? Если так, то приношу извинения.
Или же эта задача решается исключительно в целях изучения регулярных выражений? Если так, то приношу извинения.
Спустя 2 минуты, 36 секунд (19.01.2012 - 09:42) asokol написал(а):
А по регулярным выражениям в первую очередь нужно изучить мануал.
http://ru2.php.net/manual/ru/pcre.pattern.php
Если будут вопросы, то обращайтесь.
http://ru2.php.net/manual/ru/pcre.pattern.php
Если будут вопросы, то обращайтесь.
Спустя 21 минута, 46 секунд (19.01.2012 - 10:04) TinK написал(а):
Цитата (asokol @ 19.01.2012 - 06:39) |
TinK, попробуйте использовать explode. Я не проверял, но по идее explode будет работать быстрее, меньше нагрузка на процессор, к тому же проще, на мой взгляд, определять ошибки подстановки. Если не совсем понятно, каким образом пользоваться, то я постараюсь объяснить. Или же эта задача решается исключительно в целях изучения регулярных выражений? Если так, то приношу извинения. |
нет, задача в полне практическая...
explode не подходит - зачем мне дублировать весь объем шаблона разбивая его разделителем (или я не правильно понял описание функции) ?
мне просто нужны выражения удовлетворяющие регулярке найти, распознать, сгенерить замену и заменить все одинаковые выражения этим сгенерированным контентом.
Спустя 41 минута, 48 секунд (19.01.2012 - 10:45) killer8080 написал(а):
TinK
ну понятно, сначала мы создаем проблему, а потом героически с ней боремся
Что мешает вместо {{bla:{{blin}}}} сделать {bla:blin}?
ну понятно, сначала мы создаем проблему, а потом героически с ней боремся
Что мешает вместо {{bla:{{blin}}}} сделать {bla:blin}?
Спустя 39 минут, 56 секунд (19.01.2012 - 11:25) TinK написал(а):
1) то что {{blin}} может быть что угодно...
2) то что вместо {{blin}} должно подставиться что-то ещё, например {{bla:index}}
3) двойные скобки потому что в тексте могут встречаться {, а {{ нет
2) то что вместо {{blin}} должно подставиться что-то ещё, например {{bla:index}}
3) двойные скобки потому что в тексте могут встречаться {, а {{ нет
Спустя 6 минут, 6 секунд (19.01.2012 - 11:31) asokol написал(а):
{{bla:{{blin}}}}
1. Сначала разбиваете по {{
2. Затем каждый элемент полученного массива (кроме 0) проверяете на наличие }}. Если присутствует, то значит substr до начала }} - это будет ключевое слово. Если нет, значит, элемент целиком ключевое слово (в нашем случае - bla:), но в следующем элементе массива будет вложенное ключевое слово (blin). Дальше разжевывать не буду.
1. Сначала разбиваете по {{
2. Затем каждый элемент полученного массива (кроме 0) проверяете на наличие }}. Если присутствует, то значит substr до начала }} - это будет ключевое слово. Если нет, значит, элемент целиком ключевое слово (в нашем случае - bla:), но в следующем элементе массива будет вложенное ключевое слово (blin). Дальше разжевывать не буду.
Спустя 2 часа, 3 минуты, 33 секунды (19.01.2012 - 13:35) killer8080 написал(а):
Цитата (TinK @ 19.01.2012 - 10:25) |
двойные скобки потому что в тексте могут встречаться {, а {{ нет |
Откуда оно возьмется в tpl файле, если ты сам это там не пропишешь?
Спустя 6 минут, 13 секунд (19.01.2012 - 13:41) asokol написал(а):
killer8080, имеется в виду, что в оформлении страницы или, например, в javascript-коде могут встречаться { и }, которые будут обрабатываться парсером зазря.
Спустя 15 минут, 40 секунд (19.01.2012 - 13:57) killer8080 написал(а):
asokol
Цитата (asokol @ 19.01.2012 - 12:41) |
имеется в виду, что в оформлении страницы или, например, в javascript-коде могут встречаться { и }, которые будут обрабатываться парсером зазря. |
поэтому нужно использовать такую последовательность, которая не может встречаться в html, js, например {*key*}
Спустя 1 день, 30 минут, 18 секунд (20.01.2012 - 14:27) TinK написал(а):
логично... спасибо, буду пробовать, а то шлак какой-то получается...
Спустя 2 часа, 41 минута, 15 секунд (20.01.2012 - 17:08) TinK написал(а):
Регулярку раскусил, задачу практически решил... Спасибо за наводки
Остановился на такой регулярке: #\{\*[A-z][-A-z0-9]*(:\{\*[A-z][-A-z0-9_]*\*\}){0,1}\*\}#i
Осталось пара вопросов:
1) как получить слова без крайних скобок {* и *} ?
т.е. что бы было просто slovo вместо {*slovo*}
2) можно сделать рекурсивную регулярку ?
т.е. что бы выражение {*slovo:{*slovo:{*slovo:{*slovo*}*}*}*} имело место быть ...
такое возможно ?
Остановился на такой регулярке: #\{\*[A-z][-A-z0-9]*(:\{\*[A-z][-A-z0-9_]*\*\}){0,1}\*\}#i
Осталось пара вопросов:
1) как получить слова без крайних скобок {* и *} ?
т.е. что бы было просто slovo вместо {*slovo*}
2) можно сделать рекурсивную регулярку ?
т.е. что бы выражение {*slovo:{*slovo:{*slovo:{*slovo*}*}*}*} имело место быть ...
такое возможно ?
Спустя 4 минуты, 3 секунды (20.01.2012 - 17:13) Winston написал(а):
Так короче будет
#\{\*[a-z][-a-z\d]*(:\{\*[a-z][-\w]*\*\})?\*\}#i
Цитата (TinK @ 20.01.2012 - 16:08) |
можно сделать рекурсивную регулярку |
Можно. Буду дома напишу, если никто не напишет.
Спустя 3 часа, 4 минуты, 16 секунд (20.01.2012 - 20:17) TinK написал(а):
Цитата (Winston @ 20.01.2012 - 14:13) | ||
Так короче будет <pre class="sh_sourceCode" rel="code">#\{\*[a-z][-a-z\d]*(:\{\*[a-z][-\w]*\*\})?\*\}#i</pre>
Можно. Буду дома напишу, если никто не напишет. |
Кажется разобрался сам...
Радует, что рекурсивное регулярное выражение заметно похудело в сравнении с исходным:
#\{\*[a-z][-a-z0-9]*(:\{\*[a-z][-a-z0-9_]*\*\}){0,1}\*\}#i
Может кому пригодится сия рекурсивная регулярка:#\{\*[a-z][-\w]*(:(?R))?\*\}#i
Спустя 48 минут, 14 секунд (20.01.2012 - 21:05) Winston написал(а):
Цитата (TinK @ 20.01.2012 - 19:17) |
Кажется разобрался сам... |
Ну вот и молодец! Так бы все.
Спустя 6 минут, 40 секунд (20.01.2012 - 21:12) TinK написал(а):
Остался только один вопрос
Цитата (TinK @ 20.01.2012 - 14:08) |
как получить слова без крайних скобок {* и *} ? т.е. что бы было просто slovo вместо {*slovo*} |
тут я в тупике...
Спустя 22 минуты, 10 секунд (20.01.2012 - 21:34) Winston написал(а):
Так?
#\{\*([a-z][-\w]*)(:(?R))?\*\}#i
Спустя 26 минут, 8 секунд (20.01.2012 - 22:00) TinK написал(а):
Спасибо, действительно - все гениальное просто :)
Попробовал по аналогии с рекурсией так же сделать:
Получается что в рекурсии нельзя избавится от ненужных символов средствами регулярки и preg_match_all ?
Попробовал по аналогии с рекурсией так же сделать:
#\{\*([a-z][-\w]*)(:((?R)))?\*\}#iно в результате избавился только от двоеточия...
Array
(
[0] => Array
(
[0] => {*page_title*}
[1] => {*web_basepath*}
[2] => {*blank:{*page_bodyid*}*}
[3] => {*blank:{*blank:{*page_bodyid*}*}*}
)
[1] => Array
(
[0] => page_title
[1] => web_basepath
[2] => blank
[3] => blank
)
[2] => Array
(
[0] =>
[1] =>
[2] => :{*page_bodyid*}
[3] => :{*blank:{*page_bodyid*}*}
)
[3] => Array
(
[0] =>
[1] =>
[2] => {*page_bodyid*}
[3] => {*blank:{*page_bodyid*}*}
)
)
Получается что в рекурсии нельзя избавится от ненужных символов средствами регулярки и preg_match_all ?