[regexp]

vlfdimir58

Посоветуйте, как сделать следующее:
Найти и заменить на что-нить текст, содержащийся между соседними знаками @, причем эти знаки не должны сидеть внутри некоторого тега [tag][/tag]:
Пример:
[tag]blablabla[/tag] [tag] bla @ [/tag] @ blabla @
на выходе я должен иметь следующее:
[tag]blablabla[/tag] [tag] bla @ [/tag] @megar blabla @megareplace
foo1 не должен быть заменен, так как содержится внутри тега [tag]

kruzer25

Ну сначала замени те @, которые внутри tag, на что-нибудь другое, потом сделай то, что надо, потом сделай обратное первому пункту.

vlfdimir58

это замечательно, конечно.
Подскажи тогда как искать такие пары @...@ внутри тегов?

vook

Вот решение на Лиспе, думаю что на любом другом языке с регэкспами все делается аналогично.
(defun replace-outside-tags (str)
(cl-ppcre:regex-replace-all "(\\[tag\\].*?\\[/tag\\])|(@.*?@)" str #'replace-1 :simple-calls t
(defun replace-1 (match &rest rest)
(if (eql (elt match 0) #\[)
match
(replace-2 match
(defun replace-2 (match)
; ...здесь происходит замена @ на @m foo...
)

erotic

Прогу на PHP накатал. В одно выражение сделать не получилось, но получилось в несколько )

<html>
<body>
<?php
$in_str = " @ [tag]blablabla[/tag] ### #[tag] bla @ [/tag] [tag] @ [tag] @ [/tag] @test3 [/tag] @ blabla @";
$repl_str = "megareplace";
$out_str = preg_replace("/#/", "\\#", $in_str);
do
{
$tmp = $out_str;
$out_str = preg_replace("#(\[tag\].*?)@(?=.*\[/tag\])#", "\\1#", $out_str);
}
while ($tmp != $out_str);
$out_str = preg_replace("#@(.*?)@#", "@$repl_str\\", $out_str);
$out_str = preg_replace("/(?<!\\\\)#/", "@", $out_str);
$out_str = preg_replace("/\\\#/", "#", $out_str);
echo "\$in_str = $in_str<br>";
echo "\$repl_str = $repl_str<br>";
echo "\$out_str = $out_str<br>";
?>
</body>
</html>

vook

буэээ....

vlfdimir58

думаю что на любом другом языке с регэкспами все делается аналогично.
Мерси за идею.
Если я ниче не перепутал, то все делается вот так:
<?php
function myReplace($str) {
if (substr($str, 0, 1) == '@') {
return '@' . 'megareplace' . substr($str, 1);
}
return $str;
}
$in = '[tag]blablabla[/tag] [tag] bla @ [/tag] @ blabla @';
$out = preg_replace("#(\[tag\].*?\[\/tag\])|(@.*?@)#e", "myReplace('$1' . '$2')", $in);
echo $out;
?>

erotic

Хойня =)
C вложенными тегами [tag][tag][/tag][/tag] не работает.

vlfdimir58

ну я не говорил, что тег [tag] может быть вложенным. В моем случае такой вложенности не бывает.

erotic

Вот блин. А я так старался
Оставить комментарий
Имя или ник:
Комментарий: