Помогите с регулярным выражением.

Бочонок

http://frontender.info
Помогите с регулярным выражением.

Доброго времени суток.


Есть текст вида:

текст
//метка 1//
текст
//метка 1 конец//
текст
//метка 1//
текст
//метка 1 конец//
текст


Нужно удалить все

//метка 1//
текст
//метка 1 конец//

я написал

PHP:
$pattern ="|([\n\r\s\S]*)\n//метка 1//[\n\r\s\S]*//метка 1 конец//([\n\r\s\S]*)|";
$replacement="\${1}\${2}";
$lib = preg_replace($pattern, $replacement, $lib, -1);
Однако столкнулся с тем, что удаляется только пследняя.

Насколко я понимаю все дело в стом что для остальных образуется нопределенность

//метка 1//
текст
//метка 1 конец//
текст
//метка 1//
текст
//метка 1 конец//

(Я правильно понял? Или у меня полночный бред?)

Вопрос: как составить регулярное выражение так что бы оно не включало в промежуток между

//метка 1// и //метка 1 конец// строку //метка 1// ?
 

hermit_refined

Отшельник
Бочонок
sorry, но рябит уже в глазах от этих "текст текст текст текст".
не скажу, что/чем это так уж важно, но...
уважайте, пожалуйста, форум - описывайте реальные ситуации.
 

Андрейка

Senior pomidor developer
а что обозначает ([\n\r\s\S]*) и почему именно так, а не иначе?
а почему выбран такой оригинальный способ удаления? \${1}\${2}
ну и для общего развития на сайте было пару статей про регулярки, надо прочитать
 

Бочонок

http://frontender.info
2hermit_refined:Примите мои извинения. Я не хотел нагружать вопрос кучей лишних подробностей и нюансов. Мне показалось что подобная абстракция позволит лучше выделить проблему с которой столкнулся.


Андрейка:
а что обозначает ([\n\r\s\S]*) и почему именно так, а не иначе?
Ну вообще то должно быть так [\s\S]* =)
\n\r - это последствие того что я сначала использовал "." а она означает любой символ кроме перевода строки. А вот почему я его не убрал после замены на \s\S - загадка полночного мышления.

а почему выбран такой оригинальный способ удаления? \${1}\${2}
А что у такого способа есть противопоказания?
Помоему вполне логичное решение. Подскажете лучшее? Я был бы вам очень признателен...

ну и для общего развития на сайте было пару статей про регулярки, надо прочитать
Я их в общем то читал... Сейчас еще раз посмотрю - возможно я что то пропустил...
 

Фанат

oncle terrible
Команда форума
Бочонок
откуда такая уверенность в том что ты знаешь, какие подробности лишние, а какие - нет?
 

Бочонок

http://frontender.info
2Апокалипсис:

Есть библиотека функций обслуживающая работу CMS.
CMS работает на модульной основе.
При установке новых модулей запускается некий файл install.php который:
а. подключаке ноые функции, которые обслуживают модуль.
б. копируют дополнительные страницы, которые позволяют например настраивать модуль.
в. добавляет в библиотеку в оперделенных местах необходимый код, когда стандартные функции CMS должны выполнять действия специфичные для модуля в рамках действия общих для всей CMS.

И некий файл uninstall.php который уничтожает все последствия действий install.php.

Вставка кода происходит в оперделенные гнезда. например:
PHP:
//Подключаемые библиотеки//
//Подключаемые библиотеки конец//

//Удаление модулей раздела//
//Удаление модулей раздела конец//

//Сборка точки//
//Сборка точки конец//
Код каждого модуля ограничен схожими метками.
Например из install.php:

PHP:
echo "<div>Считываю библиотеку <span class='red'>../../lib.php</span>.</div>";
flush();
$lib = file_get_contents('../../lib.php');

echo "<div>Добавляю подключаемые функции в библиотеку <span class='red'>modules/horizontal_menu/inc/functions.php</span>.</div>";
flush();

$pattern ="|([\s\S]*//Подключаемые библиотеки//)([\s\S]*//Подключаемые библиотеки конец//[\s\S]*)|i";
$replacement="\${1}\n//Горизонтальное меню//\n
require_once 'modules/horizontal_menu/inc/functions.php';\n
//Горизонтальное меню конец//\${2}";
$lib = preg_replace($pattern, $replacement, $lib);

echo "<div>Добавляю процедуру сборки <span class='red'>modules/horizontal_menu/inc/render.php</span>.</div>";
flush();

$render = file_get_contents('inc/render.php');

$pattern ="|([\s\S]*//Сборка точки//)([\s\S]*//Сборка точки конец//[\s\S]*)|i";
$replacement="\${1}\n".$render."\${2}";
$lib = preg_replace($pattern, $replacement, $lib);
при этом в inc/render.php например следующий код:
PHP:
//Горизонтальное меню//
	case 'Горизонтальное меню':
		$template= str_replace($points[0][$i],$points[0][$i].get_level_h_menu($id),$template);
	break;
//Горизонтальное меню конец//
Для того что бы убрать все изменения из библиотеки мне достаточно удалить все, что находится между метками

//Горизонтальное меню//
...
//Горизонтальное меню конец//

включая сами метки.
Таким образом я это сделать не могу, удаляется только последнее фхождение:
PHP:
$pattern ="|([\s\S]*)\n//Горизонтальное меню//[\s\S]*//Горизонтальное меню конец//([\s\S]*)|";
$replacement="\${1}\${2}";
$lib = preg_replace($pattern, $replacement, $lib, -1);
Так что сейчас я перечитываю документацию по регулярным выражениям и пытаюсь сообразить как запретить нахождение между метками начальной или конечно метки того же типа.

Описал реальную ситуацию.


2Фанат:
откуда такая уверенность в том что ты знаешь, какие подробности лишние, а какие - нет?
На основе моего понимания проблемы, с которой я столкнулся.
Естественно я могу ошибатся.
Но зато когда я не ошибаюсь - основываясь на сублимации данных касающихся проблемы решить обычно ее гораздо легче.
Конечно если я вывалю горы кода - то я вряд ли что то упущу. И из этих гор можно будет 100% выделить все что необхродимо для решения проблемы а заодно и отыскать пару проблем и несуразиц, которые я упустил. Но не много найдется героев, которые захотят в этом все разбиратся.
Хотя тем кто на такое способен - низкий поклон. Потому что польза от их советов неизмерима и сами они достойны искреннего уважения.

-~{}~ 31.03.07 15:43:

Попробовал использовать "Опережающую неготивную проверку"...
PHP:
|([\s\S]*)\n//Горизонтальное меню//(?<!//Горизонтальное меню//)[\s\S]*//Горизонтальное меню конец//([\s\S]*)|
Но что то помоему я ерунду написал.
1. скрипт начинает потреблять все ресурсы системы и его приходится убивать. непонятно почему такое происходит...
2. [\s\S]* - после проверки может включать что угодно :(
кроме того до "Горизонтальное меню" тоже может быть что угодно. :(

-~{}~ 31.03.07 17:55:

Неужели ничего не подскажете?
У меня пока ничего не получилось...
 

Андрейка

Senior pomidor developer
\n\r - это последствие того что я сначала использовал "." а она означает любой символ кроме перевода строки.
такс.. мануал - CXVII. Функции для работы с регулярными выражениями (Perl-совместимые) - Модификаторы шаблонов & Синтаксис регулярных выражений.. читать вдумчиво

Помоему вполне логичное решение. Подскажете лучшее?
задачка - пользуясь только функциями strpos substr str_replace удалить из любой строки символ "q". ответ мона написать тут же
 

Бочонок

http://frontender.info
Синтаксис регулярных выражений.. читать вдумчиво
Читаю.

Метасимволы
...
. соответствует любому символу, кроме перевода строки (по умолчанию)
...
\n перевод строки (шестнадцатиричный код 0A)
задачка - пользуясь только функциями strpos substr str_replace удалить из любой строки символ "q". ответ мона написать тут же
Можно. Только вместо одного регулярного выражения и одной замены мне придется писать скрипт который последовательно будет искать и выбирать метки. Зачем?
Я полагаю что выиграш в быстродействии функций обработки строк относительно регулярных выражений в данном контексте не столь значителен.

-~{}~ 31.03.07 19:04:

если вообще будет.
 

Бочонок

http://frontender.info
В смысле?

-~{}~ 31.03.07 19:41:

У метода с использованием strpos substr str_replace есть другие какие то достоинства?
Или регулярные выражения не поволяют сделать такую замену?
По идее должны... просто я не могу сообразить.
Конечно если так ничего и не придумаю и вы не подскажете придется использовать strpos substr str_replace.
Но хотелось бы все таки разобратся с регулярным выражением.

-~{}~ 31.03.07 19:52:

Кстати, зачем str_replace не совсем понятно. Вроде бы достаточно strpos и substr со strlen.
Впрочем не важно.
Так что то по поводу регулярных выражений посоветуете?

-~{}~ 31.03.07 20:03:

Так... Судя по реплике Фаната я сморознул несусветную чушь.
Но пока не могу понять - где.
Андрейка, вы это имели в виду или что то совершенно иное, чего я не понял? Если я неправильно понял - извините и обьясните, если вам не сложно, подробнее...

PHP:
$open_label = '//Горизонтальное меню//';
$close_label = '//Горизонтальное меню конец//';
while(($pos1=strpos($lib,$open_label))!==false){
	$pos2 = strpos($lib,$close_label,$pos1);
	$part1 = substr($lib,0,$pos1-1);
	$part2 = substr($lib,$pos2+strlen($close_label));
	$lib =$part1.$part2;
}
Так или иначе - эти "костыли" не выход из положения.
Помогите мне решить эт задачу с помощью рег. выражений пожалуста.

-~{}~ 31.03.07 20:06:

Фанат, если уж сказал "А", то, если тебя не затруднит, скажи пожалуста "Б". В чем я по твоему мнению ошибаюсь. Я охотно изменю свою точку зрения на проблему, если твоя точка знрения на нее более рациональна и целесообразна в данном контексте.
 

Фанат

oncle terrible
Команда форума
кромсать регулярками готовые скрипты - такое мне в страшном сне не приснится.
я-то, по наивности думал, что для таких целей служит модульность, файлы настройки, то-сё.
А здесь такой прогрессивный метод, что сказать мне нечего.
 

Бочонок

http://frontender.info
А можно поподробнее - как это реализовать по другому? Более рационально?
Или пошлите почитать что то?
Хотелось бы сделать оптимальным образом, но я пока не понимаю как менять функциональные возможности CMS не меняя ее кода.

Есть например функция которая удаляет модули, которые присвоены определенной странице.
Но некоторые модули используют дополнительные такблицы с некой информацией. Ее тоже надо удалить. И удаление это должно происходить при вызове общей для CMS функции удаления. Как ее заставить это сделать, не меняя ее кода?

Как альтернатива - только написать функцию удаления для каждого модуля свою. Но при этом такой подход обладает коллосальной избыточностью... Кроме того библиотеки, которые индивидуальны для модуля надо как то подключать.
Каким образом это можно сделать не кромсая скрипты?
Надо же как то туда добавить в них злощастный require_once...

Я был бы вам очень признателен ечли бы вы обьяснили как это стоит делать и/или указали литературу, из которой я мог бы почерпнуть необходимую "теорию", проверенную практикой и доказывающую что тот или иной подход более разумен.

-~{}~ 31.03.07 20:34:

или имеется в виду что надо создать какой то промежуточный файл в него загнать список связок

тип модуля : функция

и список подключаемых библиотек

и когда настает время выполнения специфичных для модуля действий обращатся к этому буфферному файлу?
но даже если там содержится название функции, которая должна выполнить специфичные действия то как запустить функцию с этим названиям?

-~{}~ 31.03.07 20:37:

Конечно если добавлять в некий include_list.xml пути подключения библиотек модулей то проблема с добавлением require_once исчерпает себя... Хотя include_list.xml все равно придется кромсать. Но это по крайней мере не исполняемый скрипт.
(кстати, вопрос - а почему ээто лучше? только с точки зрения разделения скриптов и изменяемой части?)

-~{}~ 31.03.07 20:38:

можно в php как то запускать php код содержащийся в строке?

-~{}~ 31.03.07 20:39:

или я опять не в ту сторону смотрю?

-~{}~ 31.03.07 20:46:

Кстати - а почему не стоит кромсать скрипт?
Если ввести систему файлов конфигурации то теряется время на их парсинге...
Правда система получается более структурирована.
Скрипт не меняется.меняются только отдельные и специально выбраные файлы.
Какие достоинства у метода с использованием доп. фалов кроме структуры и невозможности "грохнуть" основной скрипт?
Обьясните пожалуста.

-~{}~ 31.03.07 20:49:

Запуск функций осуществляется с помощью php.net/call_user_func_array
так?

-~{}~ 31.03.07 20:52:

Впрочем кромсать, пусть не скрипт а файлы настроек придется.
Так что вопрос заданный в начале - остается очень даже актуальным.
Просто возникла куча новых вопросов.
(Я же говорил что они возникнут если предоставить развернутое представление проблемы... - что впрочем хорошо и даже замечательно)

Очень надеюсь на ваши советы и заранее благодарен за любую подсказку или пояснение, касательно данных вопросов.

-~{}~ 31.03.07 22:04:

--------------------------------------
Попробовал.
PHP:
$pattern ="|(.*)\n//метка 1//.*?//метка 1 конец//(.*)|s";
$replacement="\${1}\${2}";
$lib = preg_replace($pattern, $replacement, $lib, -1);
Опять удалило только последнее вхождение...
Даже не знаю в чем может быть дело :(
Подскажите что не так в регулярном выражении... .*? по идее должно было заставить выражение искать вхождение минимальной длины.
 
Сверху