Регулярное выражение для парсера шаблона

  • Автор темы Автор темы wollk
  • Дата начала Дата начала

wollk

Новичок
День добрый! Не могу написать регулярку для разборки шаблона
Допустим есть такой шаблон:
HTML:
dfdfg
        dfgdfg
        fdg

        --BLOCK_NO--
        11111
        --BLOCK_MAIN--ccc
        222222
Как мне получить название блока (NO, MAIN) и соответственно содержание (11111, ссс 2222..)
Написал такое:

PHP:
preg_match_all('/--BLOCK_([\w\d]+)[^>:-]*--(.*?)(?<!--BLOCK)/uis',$value,$blocks_reg,PREG_SET_ORDER);
Названия блоков парсятся, а вот их содержимое - нет (
 
День добрый! Не могу написать регулярку для разборки шаблона
Допустим есть такой шаблон:
HTML:
dfdfg
        dfgdfg
        fdg

        --BLOCK_NO--
        11111
        --BLOCK_MAIN--ccc
        222222
Как мне получить название блока (NO, MAIN) и соответственно содержание (11111, ссс 2222..)
Написал такое:

PHP:
preg_match_all('/--BLOCK_([\w\d]+)[^>:-]*--(.*?)(?<!--BLOCK)/uis',$value,$blocks_reg,PREG_SET_ORDER);
Названия блоков парсятся, а вот их содержимое - нет (
Насколько я понимаю "(.*?)(?<!--BLOCK)" это условие нахождения * если за ним не идет --BLOC, тогда верно, у тебя после каждого содержимого идет --BLOCK и оно не попадает под условие
P.S. могу быть не прав.
 
Насколько я понимаю "(.*?)(?<!--BLOCK)" это условие нахождения * если за ним не идет --BLOC, тогда верно, у тебя после каждого содержимого идет --BLOCK и оно не попадает под условие
P.S. могу быть не прав.
Хм.. действительно. Но этим кодом я хотел сказать, чтобы брало все (.*?) до следующего блока --BLOCK

Если написать так /--BLOCK_([\w\d]+)[^>:-]*--(.*?)--BLOCK_([\w\d]+)[^>:-]*--/uis то все будет ок, до последнего блока, за которым нет другого блока
 
Хм.. действительно. Но этим кодом я хотел сказать, чтобы брало все (.*?) до следующего блока --BLOCK

Если написать так /--BLOCK_([\w\d]+)[^>:-]*--(.*?)--BLOCK_([\w\d]+)[^>:-]*--/uis то все будет ок, до последнего блока, за которым нет другого блока
Извиняюсь за плохой совет, но почему бы для достижения результата до поиска просто не добавить финальный блок к примеру
PHP:
 preg_match_all('/--BLOCK_([\w\d]+)[^>:-]*--(.*?)--BLOCK_([\w\d]+)[^>:-]*--/uis',$value."--BLOCK_END--",$blocks_reg,PREG_SET_ORDER);
?
 
Сейчас так и есть )) Вот хочу убрать этот финальный блок, так как строки аля
HTML:
--BLOCK_NO-END--
--BLOCK_MAIN--
Бессмысленны
 
Если использовать в именах блоков тире, т.е. как тут --BLOCK_NO-END-- то регулярное выражение становится значительно тяжелее.
В таком случае необходима негативная опережающая проверка(negative look-ahead):
PHP:
$parts = preg_split('/\-\-BLOCK_((?:(?!.\-\-).)++.)\-\-/', $c, 0, PREG_SPLIT_DELIM_CAPTURE);
На русский переводится это так:
  1. Символ тире
  2. Символ тире
  3. Символ B
  4. Символ L
  5. Символ O
  6. Символ C
  7. Символ K
    1. Начало группировки для сохранения имени блока
      1. Начало группировки без сохранения
        1. Негативная опережающая проверка: любой символ после которого не идёт два символа тире
        2. Любой символ
      2. Конец группировки без сохранения
      3. Жадный захват от 1 до бесконечности символов, данный вид захвата не отдаёт символы следующим инструкциям.
      4. Любой символ.
    2. Конец группировки для сохранения имени блока.
  8. Символ тире.
  9. Символ тире.
Это регулярное выражение работает, протестировал, но применять его не рекомендую! Я его писал просто, чтобы размять мозг, обожаю регулярные выражения.
Лучше применяйте регулярное выражение выше, которое куда проще и в именах блоков не используйте тире.
 
stalxed, огромное спасибо!! За объяснения и регулярки. Очень круто! Не думал, что preg_split тут надо использовать (
 
Сверху