Эта тема на forum.dklab.ru


Mich: Отключить регулярное выражение в нужном участе
Как быстрее всего сделать следующее. Есть, допустим, код:

{b}bold{/b}
{code}
{b}bold{/b}
{/code}

Есть рег, который преобразует этот код в:

<b>bold</b>
<code>
<b>bold</b>
</code>

Как оптимальнее всего заставить рег игнорировать содержимое {code}{/code}, т.е. я хочу получить следующее:

<b>bold</b>
<code>
{b}bold{/b}
</code>


Скорость очень важна!
Миша Спларов:
Mich, вырезать во временный массив, затем из него вытаскивать и вставлять на место .
Mich:
Но вырезать придется все равно регами, так что думал может на уровне самого регулярного выражения решать?
Миша Спларов:
Mich, ессно регами. что значит на уровне рег. выраж.? Вы хотите получить конечное решение или вас интересует способ реализации?
WingedFox:
Я бы предложил такой путь:

#{(code|b)}((?:(?!{/\1}).)*?){/\\1}#<$1>$2</$1>#si

Соотв. теги перечисляются в том порядке, в котором они не могут быть вложены.

Имхо, наиболее оптимально писать большое выражение, т.к. оно будет выполняться на С.
Mich:
конечное решение или вас интересует способ реализации?
способ реализации и скорость.
Имхо, наиболее оптимально писать большое выражение, т.к. оно будет выполняться на С.
Спасибо, попробую и ваш вариант.
что значит на уровне рег. выраж.?
Типа примера WingedFox.
Миша Спларов:
То, что я имел ввиду под выдиранием (вытащено из работающей функции обработки текста):
$cnt=0;

// вытаскиваем то, что в code:
$text= preg_replace_callback ('/<code.*?<\/code>/is', 'mStore', $text);

// ворачиваем обратно:
while (preg_match('/¬([^¬]*)¬/',$text)) $text= preg_replace_callback ('/¬([^¬]*)¬/', 'mGiveback', $text);

function mStore ($tag) {
global $cnt, $tags;
$cnt++;
$tags[$cnt]=$tag[0];
return '¬'.$cnt.'¬';
};

function mGiveback ($num) {
global $tags;
return $tags[$num[1]];
};
Mich:
То, что я имел ввиду под выдиранием (вытащено из работающей функции обработки текста):
Я вас понял и уже даже сделал и пользуюсь (вариант WingedFox у меня тормозит, т.к. у меня регов с 10-ток), правда для оптимизации обратно код вставляю через strtr. Спасибо за пример. Кстати, зачем сначала проверять с preg_match, а потом preg_replace_callback. Лишняя работа?
Миша Спларов:
Mich, хм. Эта выдиралка взята из кода register'a (http://nudnik.ru/). Может вы и правы с тем, что preg_match лишний - я тоже к этому склоняюсь - уберу )
Anonymous:
$regex = array(
"/(?<!\{code\})\{b\}(.*?)\{\/b\}/s",
"/\{code\}(.*?)\{\/code\}/s");

$replace = array(
"<b>$1</b>",
"<code>$1<code>");


$subject = "
{b}sasasasa{/b}
{code}{b}bla-bla{/b}{/code}";
$find = preg_replace($regex,$replace,$subject);

Эта тема на forum.dklab.ru