regexp: замена подстроки которая не между тегами

Denjs

Новичок
regexp: замена подстроки которая не между тегами

Задача примерно такая :
есть "псевдотег1". вида
PHP:
{--tag--}
Есть "псевдотег2" "парный" вида
PHP:
<block> ... </block>
Задача заменить все {--tag--} на заданную строку, если {--tag--} находится НЕ внутри
PHP:
<block> ... </block>
при этом внутри block может находиться и другой текст.
типа
PHP:
text1 {--tag--} text2 <block> text3  {--tag--} text4 </block> <block>{--tag--}</block> <block> text5 {--tag--}</block>
где text1-text4 некий произвольный текст ранее неизвестный.

на
PHP:
text1 STRING text2 <block> text3  {--tag--} text4 </block><block> text5 {--tag--}</block>
Единственный относительно рабочий вариант который у меня получился - но он не понимает никаких text1-4:
PHP:
$str="text1 {--tag--} text2 <block> text3  {--tag--} text4 </block> <block>{--tag--}</block> <block> text5 {--tag--}</block>";
$req="/(?<!(\<block\>))\{--tag--\}(?!(\<\/block\>))/";//ok
$content=preg_replace($req,"3STRING",$str);
в ответ получаю
PHP:
text1 STRING text2 <block> text3  STRING text4 </block> <block>{--tag--}</block> <block> text5 {--tag--}</block>
при попытке вписать ".*?" в Look behind конструкцию
PHP:
(?<!(\<block\>.*?)
Получаю ошибку...

при повытке вставить (.*?) после Look behind конструкции
PHP:
(?<!(\<block\>)(.*?)\{--tag--\}(.*?)(?!(\<\/block\>))
Получаю вобще замену всего и включая text1-4.

вопроса : как описать задачу? (замена псевдотега {--tag--} вне пределов конструкции block)

т.е. правильный результат в примере - это замена только первого {--tag--} так как только он находится вне конструкции block.

Заранее спасибо.
 

Denjs

Новичок
гм...спасибо... но
"/(?<!(<block> ))(.*){\-\-tag\-\-}(.*)(?<!(<\/block> ))/U" ?
это же практически тоже самое что и
"/(?<!(<block> ))(.*?){\-\-tag\-\-}(.*?)(?<!(<\/block> ))/"
а так я пробовал...
В любом случае, подставил и "прогнал" в пример, получил на выходе строку
PHP:
"STRINGSTRINGSTRINGSTRING</block>"
а это "не то"...
 

zarus

Хитрожопый макак
Слишком заумное выражение, да и preg_replace ты неправильно используешь. Проще надо быть.
PHP:
$str = "text1 {--tag--} text2 <block> text3  {--tag--} text4 </block> <block>{--tag--}</block> <block> text5 {--tag--}</block>";
// Исходная строка
print htmlspecialchars($str).'<hr />';
$req = '/(^|<\/block>)(.*?)({--tag--})(.*?)($|<block>)/i';//ok
$content = preg_replace($req,'\1\2STRING\4\5',$str);
// Конечная строка
print htmlspecialchars($content).'<hr />';
 

Denjs

Новичок
Указанный пример заменяет третий {--tag--}, а это не совсем верно...
PHP:
text1 {--tag--} text2 <block> text3 {--tag--} text4 </block> <block>{--tag--}</block> <block> text5 {--tag--}</block>
==========================================
text1 STRING text2 <block> text3 {--tag--} text4 </block> <block>STRING</block> <block> text5 {--tag--}</block>
пока не до конца понимаю как работает твое выражение но попробую разобрать и подумать в аналогичном направлении.

Мозможно такое решение окажется в принципе приемлемым на практике.
 

zarus

Хитрожопый макак
Добавь предикаты (запрет) на <block> до {--tag--} и </block> после - и все будет в ажуре
 
Сверху