Пытаюсь заменить в строке найденные вхождения регуляркой но не совсем получается то что нужно.
Строка вида [STRING_****] (STRING_*****) /STRING
Нужно заменить все STRING кроме /STRING при этом у меня почему то заменяются и скобки.
$file = file_get_contents($_SERVER['DOCUMENT_ROOT'].'/uploads/data.txt');
$searchContext = 'STRING';
$replaceContext = 'NEW_STRING';
$pattern = '/([\[(\s])('.$searchContext.')/';
$result = preg_replace($pattern, $replaceContext, $file);
В оригинальном регулярном выражении заданы 2 захватывающие группы (подмаска), каждая из которых создаёт буфер в памяти, в котором хранится часть совпадения:
'/([\[(\s])('.$searchContext.')/'
| --1-- || ------ 2 ------- |
Содержимое этих двух групп можно "восстановить", т.е. обратиться к тексту в этих группах, с помощью обратных ссылок, которые можно использовать в шаблоне замены, используя следующий синтаксис: $ + идентификатор группы. Группа №1 — это шаблон, обрамлённый первой парой неэкранированных круглых скобок, в шаблоне замены надо использовать $1:
$result = preg_replace($pattern, "$1" . $replaceContext, $file);
^^^^
См. PHP-демо
Из описанного выше следует, что вторая захватывающая группа лишняя.
Есть ещё один способ. В захватывающей группе задан шаблон известной длины (([\[(\s]) находит один символ), поэтому можно просто преобразовать группу в блок предварительного просмотра назад и использовать
$pattern = '/(?<=[\[(\s])'.$searchContext.'/';
$result = preg_replace($pattern, $replaceContext, $file);
Ещё одно демо
Блоки предварительного просмотра не добавляют найденный текст в конечный массив значений, а также не меняет позицию в строке (т.е. шаблон этих блоков проверяется на наличие/отстутвие, а при выходе из блока поиск последующих шаблонов продолжается с того же места в строке, где начался поиск шаблона блока).
В PCRE, кроме двух описанных способов, можно воспользоваться оператором "сброса совпадения", \K:
preg_replace('/[\[(\s]\K'.$searchContext.'/', $replaceContext, $file)
И снова демо
Всё, что было найдено до \K, удаляется из буфера совпадения.
Примечание: Если в $searchContext ожидается наличие специальных метасимволов (операторов, таких как (, ), [, {, \, +, ^, $, *, ? и .), необходимо экранировать их с помощью preg_quote($searchContext, '/'). Второй параметр экранирует разделитель регулярного выражения (в данном случае, /).
Современные инструменты для криптотрейдинга: как технологии помогают принимать решения
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости