19.07.2019, 16:01
|
|
Профессор
|
|
Регистрация: 06.08.2017
Сообщений: 473
|
|
Запрос 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 то такие ссылки пропускаем (не нужно ставить слеш).
Помогите пожалуйста написать такой запрос.
|
|
19.07.2019, 16:06
|
|
Профессор
|
|
Регистрация: 06.08.2017
Сообщений: 473
|
|
Что то похожее я уже сделал для атрибута src в изображениях <img src="..." />
Вот такой запрос:
UPDATE `articles` SET `content` = REPLACE(content, 'src="images/', 'src="/images/')
Но тут у меня был статический параметр images (папка с изображениями) и я смог с этим справиться самостоятельно.
|
|
19.07.2019, 17:07
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,989
|
|
Сообщение от MC-XOBAHCK
|
Запрос MySQL с регуляркой
|
А стоит ли это делать в свете переезда? Если переезжаем, значит заменить нужно один раз, следовательно выгоднее взять как есть из базы, средствами серверного скрипта заменить все на нужное и сохранить. Не знаю, что у вас за серверный язык, но в нем рег. выражения намного богаче.
PS. Может вообще задуматься на тем, чтобы хранить такие вещи как переменные, а то опять с переездом ковырять придется.
PS. Если только слеш подставить, то меняйте href=" на href="/.
Последний раз редактировалось laimas, 19.07.2019 в 17:26.
|
|
19.07.2019, 19:17
|
|
Профессор
|
|
Регистрация: 06.08.2017
Сообщений: 473
|
|
laimas, скажите пожалуйста, а в MySQL сделать такое вообще возможно?
Сообщение от laimas
|
PS. Если только слеш подставить, то меняйте href=" на href="/.
|
Так нельзя делать. А если значение href начинается с http, например href="https://javascript.ru", то тогда слеш поставиться в самом начале и ссылка сломается. Или если уже есть слеш, то их станет два что тоже плачевно для меня.
У меня 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);
}
}
}
|
|
19.07.2019, 19:40
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,989
|
|
Можно и в SQL - http://www.mysql.ru/docs/man/Regexp.html , в нем не очень то и много, но простейшее сделать можно. Можно вообще и строковыми функциями обойтись.
Но к примеру. Это у вас html со ссылками, да еще и с внутренними. Предположим, что N страниц "умерло", что тогда, выставлять битые ссылки или руками править? Хорошо если страница можно сказать статика, но если она ссылается на динамический контент, тогда могут быть неприятности. В таких случаях ссылки определяются как параметры страницы, которые подставляются при выводе. Если страница умерла или изменила адрес, то либо не будет ссылки, либо будет новый адрес. Хотя хозяину виднее.
|
|
19.07.2019, 20:05
|
|
Профессор
|
|
Регистрация: 06.08.2017
Сообщений: 473
|
|
У меня эта страница по ссылке уже два дня в браузере открыта. У меня практики нет, поэтому я теряюсь в документации. Написать запрос самостоятельно я не могу.
Почему мне это надо? Если раньше с относительными путями без слеша в начале работало всё нормально, то с переездом если нет вначале слеша, то к пути добавляется вначало путь просматриваемой страницы. В общем вся внутренняя перелинковка на сайте падает, а 404-ая становится самой популярной.
|
|
19.07.2019, 20:19
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,989
|
|
Так что у вас в ссылках - только относительные пути или же есть и абсолютные?
PS. Учтите, что MySQL может найти запись по рег. выражению, заменять же им он не может, то есть без костыля тут никак не обойтись. Почему я и говорил об однократном запуске простого скрипта - получили записи, заменили посредством РНР, сохранили.
Последний раз редактировалось laimas, 19.07.2019 в 20:31.
|
|
19.07.2019, 20:37
|
|
Профессор
|
|
Регистрация: 06.08.2017
Сообщений: 473
|
|
Есть относительные такого вида без слеша:
<a href="forum/server>Серверные языки и технологии</a>
Есть со слешем:
<a href="/forum/server>Серверные языки и технологии</a>
Есть с полными путями (они на внешние ресурсы):
<a href="https://javascript.ru/forum/server>Серверные языки и технологии</a>
Относительные без слеша в начале ломаются. Нужно им проставить слеш, с учётом что есть и два других вида ссылок которые не нужно менять.
|
|
19.07.2019, 21:06
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,989
|
|
Написать простенький скрипт, который запустить один раз не проблема? В нем запрос - получить все всех записей (объем таблицы позволит?), затем обходом готовим массив, заменяя в нужном поле ссылки:
$s = preg_replace ('/href="(?!\/|https?)/m', 'href="/', $s);
где $s, это значение этого поля.
Затем очищаем таблицу (TRUNCATE), после чего многострочной вставкой заносим массив с изменениями. Можно, конечно, в цикле и обновлять только одно значение полученное запросом, но это более накладная операция.
|
|
19.07.2019, 21:44
|
|
Профессор
|
|
Регистрация: 06.08.2017
Сообщений: 473
|
|
laimas, Спасибо!
Я идею понял. В ларавеле там с запросами не сложно. Буду пробовать.
|
|
|
|