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

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);
Названия блоков парсятся, а вот их содержимое - нет (
 

Kotofey

FloodMaster.
День добрый! Не могу написать регулярку для разборки шаблона
Допустим есть такой шаблон:
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. могу быть не прав.
 

wollk

Новичок
Насколько я понимаю "(.*?)(?<!--BLOCK)" это условие нахождения * если за ним не идет --BLOC, тогда верно, у тебя после каждого содержимого идет --BLOCK и оно не попадает под условие
P.S. могу быть не прав.
Хм.. действительно. Но этим кодом я хотел сказать, чтобы брало все (.*?) до следующего блока --BLOCK

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

Kotofey

FloodMaster.
Хм.. действительно. Но этим кодом я хотел сказать, чтобы брало все (.*?) до следующего блока --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);
?
 

wollk

Новичок
Сейчас так и есть )) Вот хочу убрать этот финальный блок, так как строки аля
HTML:
--BLOCK_NO-END--
--BLOCK_MAIN--
Бессмысленны
 

stalxed

Новичок
Если использовать в именах блоков тире, т.е. как тут --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. Символ тире.
Это регулярное выражение работает, протестировал, но применять его не рекомендую! Я его писал просто, чтобы размять мозг, обожаю регулярные выражения.
Лучше применяйте регулярное выражение выше, которое куда проще и в именах блоков не используйте тире.
 

wollk

Новичок
stalxed, огромное спасибо!! За объяснения и регулярки. Очень круто! Не думал, что preg_split тут надо использовать (
 
Сверху