Запрос MySQL с регуляркой
Здравствуйте! Прошу помощи написать запрос для MySQL с регулярным выражением.
Нужно в содержимом столбца найти атрибуты href="..." и проставить в них перед значениями слеш, при условии что значение не начинается с http или со слеша / Опишу суть подробнее. В БД у меня есть таблица articles. В этой таблице есть столбец content В столбце content хранится html статей. Проблема в том, что в статьях есть ссылки на внутренние страницы сайта. Прописаны они без домена и перед ними нет слеша. Пример таких ссылок: <a href="forum">Форум JavaScript</a> <a href="forum/misc>Общие вопросы</a> <a href="forum/server>Серверные языки и технологии</a> До сих пор отсутствие слеша мне не мешало и всё работало. Но теперь сайт переезжает и нужно в таких значениях проставить слеши, то есть чтобы стало так: <a href="/forum">Форум JavaScript</a> <a href="/forum/misc>Общие вопросы</a> <a href="/forum/server>Серверные языки и технологии</a> Для поиска есть такая статическая часть: [ href="] вначале есть пробел, а в конце - одна двойная кавычка. После кавычки идут английские буквы. Если в начале значения уже есть слеш / или значение начинается с http то такие ссылки пропускаем (не нужно ставить слеш). Помогите пожалуйста написать такой запрос. |
Что то похожее я уже сделал для атрибута src в изображениях <img src="..." />
Вот такой запрос: UPDATE `articles` SET `content` = REPLACE(content, 'src="images/', 'src="/images/') Но тут у меня был статический параметр images (папка с изображениями) и я смог с этим справиться самостоятельно. |
Цитата:
PS. Может вообще задуматься на тем, чтобы хранить такие вещи как переменные, а то опять с переездом ковырять придется. PS. Если только слеш подставить, то меняйте href=" на href="/. |
laimas, скажите пожалуйста, а в MySQL сделать такое вообще возможно?
Цитата:
У меня php 7.2. Переезжает сайт - это я его с joomla переношу на OctoberCMS (laravel). Статьи импортирую со старого сайта на новый. С регулярками у меня беда - я за помощью часто на форуме обращаюсь по ним. В php вообще никогда регулярки не писал. Если это поможет, вот функция импорта: public function importData($results, $sessionKey = null) { $firstRow = reset($results); foreach ($results as $row => $data) { try { // Создаем новую запись $item = Item::make(); // Исключить из цикла $except = ['id']; // В этом массиве мы исключаем те переменные, которые не нужно обрабатывать в автоматическом цикле foreach ниже // Цикл заполнения foreach (array_except($data, $except) as $attribute => $value) { $item->{$attribute} = $value ?: null; // Присваивание значения в столбец по атрибуту } // Сохранение $item->save(); $this->logCreated(); } catch (\Exception $ex) { // Ошибка $this->logError($row, $ex); } } } |
Можно и в SQL - http://www.mysql.ru/docs/man/Regexp.html , в нем не очень то и много, но простейшее сделать можно. Можно вообще и строковыми функциями обойтись.
Но к примеру. Это у вас html со ссылками, да еще и с внутренними. Предположим, что N страниц "умерло", что тогда, выставлять битые ссылки или руками править? Хорошо если страница можно сказать статика, но если она ссылается на динамический контент, тогда могут быть неприятности. В таких случаях ссылки определяются как параметры страницы, которые подставляются при выводе. Если страница умерла или изменила адрес, то либо не будет ссылки, либо будет новый адрес. Хотя хозяину виднее. |
У меня эта страница по ссылке уже два дня в браузере открыта. У меня практики нет, поэтому я теряюсь в документации. Написать запрос самостоятельно я не могу.
Почему мне это надо? Если раньше с относительными путями без слеша в начале работало всё нормально, то с переездом если нет вначале слеша, то к пути добавляется вначало путь просматриваемой страницы. В общем вся внутренняя перелинковка на сайте падает, а 404-ая становится самой популярной. |
Так что у вас в ссылках - только относительные пути или же есть и абсолютные?
PS. Учтите, что MySQL может найти запись по рег. выражению, заменять же им он не может, то есть без костыля тут никак не обойтись. Почему я и говорил об однократном запуске простого скрипта - получили записи, заменили посредством РНР, сохранили. |
Есть относительные такого вида без слеша:
<a href="forum/server>Серверные языки и технологии</a> Есть со слешем: <a href="/forum/server>Серверные языки и технологии</a> Есть с полными путями (они на внешние ресурсы): <a href="https://javascript.ru/forum/server>Серверные языки и технологии</a> Относительные без слеша в начале ломаются. Нужно им проставить слеш, с учётом что есть и два других вида ссылок которые не нужно менять. |
Написать простенький скрипт, который запустить один раз не проблема? В нем запрос - получить все всех записей (объем таблицы позволит?), затем обходом готовим массив, заменяя в нужном поле ссылки:
$s = preg_replace ('/href="(?!\/|https?)/m', 'href="/', $s); где $s, это значение этого поля. Затем очищаем таблицу (TRUNCATE), после чего многострочной вставкой заносим массив с изменениями. Можно, конечно, в цикле и обновлять только одно значение полученное запросом, но это более накладная операция. |
laimas, Спасибо!
Я идею понял. В ларавеле там с запросами не сложно. Буду пробовать. |
Часовой пояс GMT +3, время: 08:01. |