Запрос 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, Спасибо!
Я идею понял. В ларавеле там с запросами не сложно. Буду пробовать. |
Цитата:
А скриптом из корня, это: 1) подключаем параметры подключения к БД 2) считываем таблицу 3) вносим изменения 4) блокируем доступ к таблице 5) очищаем таблицу 6) запись в таблицу 7) снимаем блокировку с таблицы 8) удаляем скрипт Перед операцией сделайте экспорт таблицы. |
laimas, Спасибо вам! У меня всё получилось.
Регулярка отрабатывает правильно - слеш проставился только в тех случаях когда его не было. Я в скрипт ещё кучу замен добавил, только уже через str_replace() и логические выражения. Скрипт отработал легко и что самое главное - результат правильный. Большое вам СПАСИБО за помощь! |
Цитата:
|
Цитата:
Цитата:
|
Цитата:
Цитата:
|
Че хрень то городить? А вообще речь идет о переносе, и пофиг какая там CMS и на чем базируется, есть дампы таблиц, и если ее размер позволяет, то можно прошерстить сам дам перед импортом.
|
Экспортируйте таблицу
Откройте в notepad++ замените как нужно Импортируйте таблицу обратно |
Poznakomlus,
для меня такой алгоритм действий неправильный. Мне тогда сначала нужно скачать нотпад++, а потом уже всё остальное. Но саму идею я понял - проще не придумаешь. Спасибо - возьму на заметку. Свою задачу с импортом я полностью решил написав для импорта модель с интерфейсом. |
Часовой пояс GMT +3, время: 17:34. |