За последние 24 часа нас посетили 17560 программистов и 1314 роботов. Сейчас ищут 1439 программистов ...

[РЕШЕНО] Блоки внутри блоков

Тема в разделе "Регулярные выражения", создана пользователем rodent90, 22 сен 2015.

  1. rodent90

    rodent90 Новичок

    С нами с:
    26 мар 2015
    Сообщения:
    533
    Симпатии:
    37
    Приветствую всех знатоков регулярок:)
    Помогите решить костыль.
    Код (PHP):
    1. $html='{block}
    2.     0
    3.     {block1}
    4.         2
    5.     {/block1}
    6. {/block}';
    7.  
    8. preg_replace_callback('~{(.+?)}(.+?){\/\1}~si',function($reg) {
    9.     print_r($reg);
    10. },$html);
    Возвращает:
    Код (PHP):
    1. (
    2.     [0] => {block}
    3.     0
    4.     {block1}
    5.         2
    6.     {/block1}
    7. {/block}
    8.     [1] => block
    9.     [2] => 
    10.     0
    11.     {block1}
    12.         2
    13.     {/block1}
    14.  
    15. ) 
    ,
    нашло только первый.
    Почему так?
    А надо, чтобы вернуло:
    Код (PHP):
    1. (
    2.     [0] => {block}
    3.     0
    4. {/block}
    5.     [1] => block
    6.     [2] => 
    7.     0
    8.  
    9. )
    10. (
    11.     [0] => {block1}
    12.         2
    13.     {/block1}
    14.     [1] => block1
    15.     [2] => 
    16.         2
    17.     
    18. ) 
    В регулярках не силен! Помогите решить конфликт пожалуйста, будьте так добры ;)
     
  2. VLK

    VLK Старожил

    С нами с:
    15 дек 2013
    Сообщения:
    3.010
    Симпатии:
    58
    Re: Блоки внутри блоков

    ну так оно ищет каждое новое вхождение не с 0 позиции, а с последней найденной (если таковое было), в твоем случае после нахождения первого варианта поиск дальше будет идти начиная с после {/block}, т.е. твлю эту штуку надо решать по другому и кстати, забегая вперед вроде как ее так просто через регулярное выражение не решить.

    Добавлено спустя 2 минуты 7 секунд:
    вот загляни в эту тему, может в ней найдется что то полезное - viewtopic.php?f=18&t=48868&p=388664

    Добавлено спустя 38 секунд:
    и если вдруг то решение что давалось в конце (работоспособное) подойдет, скажешь, я дам более правильное.
     
  3. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    Re: Блоки внутри блоков

    а через жадность разве никак не уговорить регулярке находить куски сначала внутри, потом если их заменить и находить дальше?
     
  4. VLK

    VLK Старожил

    С нами с:
    15 дек 2013
    Сообщения:
    3.010
    Симпатии:
    58
    Re: Блоки внутри блоков

    igordata, я как понял тут проблема у него с какой позиции начинается поиск следующего вхождения, ему надо что бы с начала, а оно ищет с конца.
     
  5. rodent90

    rodent90 Новичок

    С нами с:
    26 мар 2015
    Сообщения:
    533
    Симпатии:
    37
    Re: Блоки внутри блоков

    А как это сделать?
     
  6. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    Re: Блоки внутри блоков

    если б я знал
     
  7. rodent90

    rodent90 Новичок

    С нами с:
    26 мар 2015
    Сообщения:
    533
    Симпатии:
    37
    Re: Блоки внутри блоков

    Я знаю, что есть рекурсия, но как ее активировать, не понимаю ничерта...
    Уже что только не пробовал.

    Кто-нибудь, выручайте...(((
     
  8. rodent90

    rodent90 Новичок

    С нами с:
    26 мар 2015
    Сообщения:
    533
    Симпатии:
    37
    Re: Блоки внутри блоков

    Вообщем проблема решена.
    Написал такую регулярку:
    ~{/([^}]+)\s([^}]+)}~siU
    Ну это те у которых есть еще ключ через пробел.
    {/block name}
    Нашло все конечные закрывающие теги
    А потом склеил все это
    ~{(.+?)}(.+?){\/\1\s(.+?[}]|.+?)}~si
    , заработало еху ;)
     
  9. VLK

    VLK Старожил

    С нами с:
    15 дек 2013
    Сообщения:
    3.010
    Симпатии:
    58
    хрень заключается в том, что у preg_replace_callback нельзя задать с какой позиции искать, так можно было бы сделать рекурсию.
     
  10. rodent90

    rodent90 Новичок

    С нами с:
    26 мар 2015
    Сообщения:
    533
    Симпатии:
    37
    Я пробовал спаивать разные рекурсии в одной, но результат был один и тот же, я не силен в регулярках и делал видимо не правильно.
    В чем - то там есть исход, регулярка будет длинная, я не знаю просто, что туда писать... Не могу никак еще понять их.

    Приходится жертвовать.
    Я не знаю как написать 1-ну регулярку, пришлось прогонять циклом и в цикле вызывать еще одну.
    Их очень много блоков, ну работает шустро, все это дело срабатывает 1 раз до кеширования, по этому не так важно.

    Вся логика разделяется после.