Пытаюсь заменить в строке найденные вхождения регуляркой но не совсем получается то что нужно.
Строка вида [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, '/')
. Второй параметр экранирует разделитель регулярного выражения (в данном случае, /
).
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Скажите пожалуйста как иправить sql иньекцию, если $message будет "qwe'; DROP TABLE sel_category; --"
ЗдравствуйтеСуть проблемы: есть 4 поля в БД id, category_id,brands_id, models
У меня есть вот такой XML, который прекрасно работает в SOAPIU: