Не всё удобно делать средствами PHP, а особенно, если дело касается базы. Если нам нужно удалить⁄заменить часть строки или одно слово в нескольких записях, то с использованием PHP, нам бы пришлось сначала вытаскивать каждую запись, изменять её и обновлять в БД. Не очень удобно... В некоторых случаях, всё это можно сделать одним запросом MySQL. Давайте посмотрим, как это можно сделать.
Для примера, возьмём таблицу "verses" (стихи), в которой есть записи с допущенной ошибкой в написании автора:

  1. CREATE TABLE IF NOT EXISTS `verses` (
  2.   `verse_id` int(11) NOT NULL AUTO_INCREMENT,
  3.   `verse_content` text NOT NULL,
  4.   PRIMARY KEY (`verse_id`)
  5. ) ENGINE=MyISAM DEFAULT CHARSET=utf8;

  6. INSERT INTO `verses` (`verse_content`) VALUES
  7.   ('Я к вам пишу – чего же боле? Что я могу еще сказать? А.С. Пупкин'),
  8.   ('А.С. Пупкин. У лукоморья дуб зелёный; Златая цепь на дубе том');

Теперь попробуем заменить неправильную фамилию "Пупкин" на "Пушкин". Самый простой вариант - используем функцию REPLACE() (! не путать с оператором REPLACE), которая позволит заменить все искомые вхождения (проще говоря - слова, фразы) в строке, на строку замены (нужное нам слово, фразу, символ и т.д.)

  1. UPDATE
  2.   `verses`
  3. SET
  4.   `verse_content` = REPLACE(`verse_content` , 'Пупкин', 'Пушкин');

Для тестирования можно просто выводить результат с заменой.

  1. SELECT
  2.   REPLACE(`verse_content`, 'Пупкин', 'Пушкин') AS `correct_string`
  3. FROM
  4.   `verses`;

Кстати, такой вариант (замена при выборке) тоже можно использовать, например, если у вас есть шаблон письма и вам нужно подставить имя получателя. Вот простой примерчик, для лучшего понимания:

  1. SELECT
  2.   REPLACE('Здравствуйте, [name]! Запрос получен. Рад, [name], что вы с нами.', '[name]', 'Игорь') AS `correct_string`
  3. FROM
  4.   `verses`;
  5. // результат: "Здравствуйте, Игорь! Запрос получен. Рад, Игорь, что вы с нами."

То есть, в шаблоне мы сделали метку "[name]" и в дальнейшем подставляем вместо неё реальное имя. Метка может быть любой, только следите, чтоб она не совпадала с реальным словом или фразой, которое так же может встретиться в исходной строке.

Всё это хорошо, если заменить нужно только само слово или фразу, которая нам известна. Но что делать, если мы знаем с какого момента нужно начать замену и где закончить, а что может находится между - не известно? Возьмём реальный случай из моей практики. У человека был сайт, где использовался старый подход - в статьях выводились миниатюрки изображений, а по клику на них, открывалось новое окно с увеличенным изображением. Прогресс движется вперёд и он решил использовать знакомый многим плагин "fancybox". Задача состояла в том, чтоб удалить не нужную часть "onclick" и добавить атрибут "rel", который используется в плагине для инициализации изображений. Ниже показано, что примерно было и что должно получится в итоге:

  1. // исходная строка
  2. <a href="#" onclick="window.open('/path/my_img.png','','width=350,height=200,left=200,top=200');return false;">
  3.   <img src="/path/my_img.png" alt="" ></a>

  4. // желаемый результат
  5. <a href="#" rel="group_img">
  6.   <img src="/path/my_img.png" alt="" ></a>

Если в записи необходимая замена нужна только один раз, то можно идти по такой схеме: получить подстроку до первого вхождения слова "onclick" с помощью функции SUBSTRING_INDEX(), потом вычисляем закрывающую угловую скобку тега (">"), идущую первой после "onclick", чтоб получить подстроку после неё, и конкатенируем (объединяем) полученные части строк, добавляя между ними необходимый атрибут.
Будем использовать ту же таблицу `verses` и, если вы добавите туда исходную строку, то учитываем, что её индекс будет равен "3":

  1. UPDATE
  2.   `verses`
  3. SET
  4.   `verse_content` = CONCAT(
  5.     SUBSTRING_INDEX(`verse_content`,'onclick', 1),
  6.     'rel="group_img"',
  7.     SUBSTRING(`verse_content`, LOCATE('>',`verse_content`, LOCATE('onclick',`verse_content`)))
  8.   )
  9. WHERE
  10.   `verse_id` = 3;

Для простых задач, не требующих "танцев с бубном", такой способ вполне приемлем и работать он будет, как я уже говорил, только с первыми найденными вхождениями. То есть, если мы добавим в запись еще одну такую же строку, то первая будет изменена, а вторая не тронута. Для более сложных операций, нужно искать другие подходы. Например, для замены мы не можем использовать функцию REAPLACE() с функцией REGEXP(), которая бы находила по шаблону всё, что нужно заменить в строке, но на такой случай, существуют UDF (Пользовательские функции) и одной из которых можно было бы применить в данном случае - есть MySQL UDF REGEXP, Regex replace for MySQL или PREG functions for MySQL.
Обратил внимание, что нигде не обмолвился про удаление, но уверен, что у вас и так хватило бы смекалки, что вместо фразы на которую мы меняли в примерах выше, нужно просто указывать пустую строку ;)


Задачи с заменами или удалением части строк средствами MySQL не частые. Скорее они носят одноразовый характер и сомневаюсь, что их регулярное использование оправдано. Я сторонник того, чтоб в БД попадали уже полностью подготовленные данные, над которыми при выводе не нужно ломать голову. Но все мы знаем, что случаи бывают разные (лично сталкивался) и, если с таким столкнётесь, то уже не растеряетесь.

Услуги и Цены Акции Отзывы Заказать Контакты

Пишите: 77@2828.ru Звоните: +7(985)345-6172 Правовая информация О сайте
Сайт работает на MX2VIP PRO CMS
При поддержке 2828.ru Клуба Технологии Здравого Смысла

ЗАКАЗАТЬ ЗВОНОК
Или свяжитесь с нами прямо сейчас по Телефону: +7 (985) 345-6172 WhatsApp: +7 (985) 345-61-72 Эл. почте: 1@2828.ru
ПОЛУЧИТЬ ПИСЬМО

Есть вопросы?

свяжитесь с нами прямо сейчас по Эл. почте: 1@2828.ru WhatsApp: +7 (985) 345-61-72 Телефону: +7 (985) 345-6172
СПАСИБО

✓ Отлично!

Мы благодарны Вам за интерес, проявленный к продуктам и услугам нашей компании.

Если у Вас возникнут какие-либо вопросы  или будет необходима дополнительная информация, пожалуйста,  обращайтесь к нам, мы с удовольствием Вам ответим. 

Закрыть
Упс, ошибочка вышла

✗ Упс…

Что-то пошло не так.

Лучше, попробуйте позвонить +7 (985) 345-6172

или написать E-mail: 1@2828.ru WhatsApp: +7 (985) 345-61-72

А мы подождём…