Замена текста (исключая между тегами)

Статус
В этой теме нельзя размещать новые ответы.

4erepaha13

Полезный
Регистрация
20 Июн 2009
Сообщения
157
Реакции
18
В большом массиве текста необходимо произвести массовые замены.
Для этой цели похоже что подойдет пример с пхп.нет:
PHP:
$patterns = array();
$patterns[0] = '/quick/';
$patterns[1] = '/brown/';
$patterns[2] = '/fox/';
$replacements = array();
$replacements[2] = 'bear';
$replacements[1] = 'black';
$replacements[0] = 'slow';
echo preg_replace($patterns, $replacements, $string);
Но есть заковыка - нужно оставлять неизменным текст внутри некоторых тегов
<a.*?a> (не править анкоры и титле)
<img.*?> (не править альты)
<h.*?\/h.> (не править заголовки)
и для этого надо "Для просмотра ссылки Войди или Зарегистрируйся".
Подскажите- как это все вместе увязать, потому что теорию на практику корректного синтаксиса пока подобрать не удалось.
 
Думаю можно использовать отрицаниие в регулярке
(?!слово)
 
Добрый день. Подскажите пожалуйста.
Есть регулярка eregi_replace('(((f|ht){1}tp://)[-a-zA-Z0-9@:%_\+.~#?&,()//=]+)', 'Для просмотра ссылки Войди или Зарегистрируйся', $text)

Как мне ее модифицировать так, чтобы под шаблон попадали только ссылки, которые либо начинаются с новой строки, либо содержат перед собой пробел

Добавлено через 51 секунду
Думаю можно использовать отрицаниие в регулярке
(?!слово)
я как понимаю мне (?!слово) тоже подходит... а как описать (?!пробел или новая строка)
 
подмаски и отрицания в паттерне усложнят задачу, обычно для этого достаточно просто разделить html на элементы и через foreach произвести замену с условиями

PHP:
// $html

$find_replace = array( 'find1'=>'repl1', 'find2'=>'repl2' ); // массив поиск/замена

$parts = preg_split('/(<(?:\?[^?]+\?>|[A-Za-z]+(?:[^">]+|"[^"]*")*|!(?:\[CDATA\[(?:[^\]]+|](?:[^\]]|][^>]))*]]|--(?:[^-]+|-(?!->))*--))>)/', $html, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);

foreach ($parts as $part) {
   if(!preg_match('/^<(a|img|h)/i',$part)) $part = strtr($part,$find_replace); // условие пропуска
   $res_html .= $part;
}

// $res_html;

2.
ссылки, которые либо начинаются с новой строки, либо содержат перед собой пробел

например так:
PHP:
$text = preg_replace('#(?:^|\s)((f|ht)tp://)\S+#im','\\1',$text);
 
подмаски и отрицания в паттерне усложнят задачу, обычно для этого достаточно просто разделить html на элементы и через foreach произвести замену с условиями
Эта регулярка сломала мозг и помоему там есть чтото сверх того, что мне нужно :)

Решил написать свою,
PHP:
$parts = preg_split('/(<img[^>]*?>|<a\s.*?>.*?a>|<h\d.*?h\d>)/i', $html, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
навскидку работает.
 
Я делал подобную задачу так - заменял все тэги на вставки типа ###TAG1### и собирал эти тэги в массив. Получал сплошной текст. Изменял его регуляркой без всяких там опережений и потом заменял тэги обратно. Для скорости можно использовать модификатор e.
 
Метод Pitkina оказался таки самым простым и эффективным, а в результате обкатки регулярка пришла к такому конечному виду
PHP:
<.*?>|<a\s.*?>.*?a>|<h\d.*?h\d>
Т.е. не править в любых одиночных тегах, не править в ссылках и в заголовках.
Самое интересное, что именно к такому виду тоже пришел автор плагина
 
Статус
В этой теме нельзя размещать новые ответы.
Назад
Сверху