[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Регулярки при парсинге шаблонов страниц
TinK
Здравствуйте, знатоки, подскажите начинающему в регулярках....

Есть шаблоны страниц, хранящихся в файлах (или в БД - не суть важно), в которых встречаются определенного вида выражения для подстановки.
Заранее неизвестно ни какие выражения будут в шаблоне, ни сами выражения. Известно лишь что выражения могут повторяться (не обязательно подряд) и включаться одно в другое и соответствуют шаблону #\{\{[a-z]{1}[a-z0-9_:-]+[a-z0-9]{1}\}\}#i (т.е. в двойных фигурный скобках заключено слово начинающееся с буквы; в середине может содержать буквы, цифры, двоеточие, подчеркивание или тире; обязательно должно заканчиваться буквой или цифрой).

unsure.gif Как модифицировать этот шаблон что бы он не возвращал вместо {{bla:{{blin}}}} такое {{bla:{{blin}} ?
unsure.gif Вопрос в том как получить это слово (хотя бы в фигурных скобках) ?
unsure.gif А потом заменить найденное выражение (после распознавания слова и получения / генерации замены для него) ?


PS гугл не помог в данном вопросе sad.gif помогите хотя бы вы...
подскажите хотя бы функции с помощью которых это можно реализовать ?



Спустя 1 час, 31 минута, 29 секунд (18.01.2012 - 22:16) killer8080 написал(а):
TinK
копай preg_replace() и preg_ replace_ callback() и учи регулярки wink.gif

Спустя 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() и  учи регулярки wink.gif

Спасибо за функции.
На счет регулировок - подскажите нормальный учебник (статьи я уже читал - не очень понятно по моей задаче).

Цитата (Winston @ 18.01.2012 - 19:38)
Цитата (TinK @ 18.01.2012 - 19:45)
Как модифицировать этот шаблон что бы он не возвращал вместо {{bla:{{blin}}}} такое {{bla:{{blin}} ?
А какое он должен возвращать?

Должно возвращаться {{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)
unsure.gif Как модифицировать этот шаблон что бы он не возвращал вместо {{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 будет работать быстрее, меньше нагрузка на процессор, к тому же проще, на мой взгляд, определять ошибки подстановки. Если не совсем понятно, каким образом пользоваться, то я постараюсь объяснить.

Или же эта задача решается исключительно в целях изучения регулярных выражений? Если так, то приношу извинения. smile.gif

Спустя 2 минуты, 36 секунд (19.01.2012 - 09:42) asokol написал(а):
А по регулярным выражениям в первую очередь нужно изучить мануал.
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 будет работать быстрее, меньше нагрузка на процессор, к тому же проще, на мой взгляд, определять ошибки подстановки. Если не совсем понятно, каким образом пользоваться, то я постараюсь объяснить.

Или же эта задача решается исключительно в целях изучения регулярных выражений? Если так, то приношу извинения. smile.gif

нет, задача в полне практическая...

explode не подходит - зачем мне дублировать весь объем шаблона разбивая его разделителем (или я не правильно понял описание функции) ?

мне просто нужны выражения удовлетворяющие регулярке найти, распознать, сгенерить замену и заменить все одинаковые выражения этим сгенерированным контентом.

Спустя 41 минута, 48 секунд (19.01.2012 - 10:45) killer8080 написал(а):
TinK
ну понятно, сначала мы создаем проблему, а потом героически с ней боремся smile.gif
Что мешает вместо {{bla:{{blin}}}} сделать {bla:blin}?

Спустя 39 минут, 56 секунд (19.01.2012 - 11:25) TinK написал(а):
1) то что {{blin}} может быть что угодно...
2) то что вместо {{blin}} должно подставиться что-то ещё, например {{bla:index}}
3) двойные скобки потому что в тексте могут встречаться {, а {{ нет

Спустя 6 минут, 6 секунд (19.01.2012 - 11:31) asokol написал(а):
{{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 написал(а):
Регулярку раскусил, задачу практически решил... Спасибо за наводки smile.gif
Остановился на такой регулярке: #\{\*[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>
Цитата (TinK @ 20.01.2012 - 16:08)
можно сделать рекурсивную регулярку

Можно. Буду дома напишу, если никто не напишет.

Кажется разобрался сам...
Радует, что рекурсивное регулярное выражение заметно похудело в сравнении с исходным:
#\{\*[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)
Кажется разобрался сам...

Ну вот и молодец! smile.gif Так бы все. smile.gif

Спустя 6 минут, 40 секунд (20.01.2012 - 21:12) TinK написал(а):
Остался только один вопрос
Цитата (TinK @ 20.01.2012 - 14:08)
как получить слова без крайних скобок {* и *} ?
т.е. что бы было просто slovo вместо {*slovo*}

тут я в тупике... sad.gif

Спустя 22 минуты, 10 секунд (20.01.2012 - 21:34) Winston написал(а):
Так?
#\{\*([a-z][-\w]*)(:(?R))?\*\}#i

Спустя 26 минут, 8 секунд (20.01.2012 - 22:00) TinK написал(а):
Спасибо, действительно - все гениальное просто :)

Попробовал по аналогии с рекурсией так же сделать:
#\{\*([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 ?
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.