Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 19.07.2019, 16:01
Аватар для MC-XOBAHCK
Профессор
Отправить личное сообщение для MC-XOBAHCK Посмотреть профиль Найти все сообщения от MC-XOBAHCK
 
Регистрация: 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 то такие ссылки пропускаем (не нужно ставить слеш).

Помогите пожалуйста написать такой запрос.
Ответить с цитированием
  #2 (permalink)  
Старый 19.07.2019, 16:06
Аватар для MC-XOBAHCK
Профессор
Отправить личное сообщение для MC-XOBAHCK Посмотреть профиль Найти все сообщения от MC-XOBAHCK
 
Регистрация: 06.08.2017
Сообщений: 473

Что то похожее я уже сделал для атрибута src в изображениях <img src="..." />

Вот такой запрос:
UPDATE `articles` SET `content` = REPLACE(content, 'src="images/', 'src="/images/')


Но тут у меня был статический параметр images (папка с изображениями) и я смог с этим справиться самостоятельно.
Ответить с цитированием
  #3 (permalink)  
Старый 19.07.2019, 17:07
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,989

Сообщение от MC-XOBAHCK
Запрос MySQL с регуляркой
А стоит ли это делать в свете переезда? Если переезжаем, значит заменить нужно один раз, следовательно выгоднее взять как есть из базы, средствами серверного скрипта заменить все на нужное и сохранить. Не знаю, что у вас за серверный язык, но в нем рег. выражения намного богаче.

PS. Может вообще задуматься на тем, чтобы хранить такие вещи как переменные, а то опять с переездом ковырять придется.

PS. Если только слеш подставить, то меняйте href=" на href="/.

Последний раз редактировалось laimas, 19.07.2019 в 17:26.
Ответить с цитированием
  #4 (permalink)  
Старый 19.07.2019, 19:17
Аватар для MC-XOBAHCK
Профессор
Отправить личное сообщение для MC-XOBAHCK Посмотреть профиль Найти все сообщения от MC-XOBAHCK
 
Регистрация: 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);
            }

        }
    }
Ответить с цитированием
  #5 (permalink)  
Старый 19.07.2019, 19:40
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,989

Можно и в SQL - http://www.mysql.ru/docs/man/Regexp.html , в нем не очень то и много, но простейшее сделать можно. Можно вообще и строковыми функциями обойтись.

Но к примеру. Это у вас html со ссылками, да еще и с внутренними. Предположим, что N страниц "умерло", что тогда, выставлять битые ссылки или руками править? Хорошо если страница можно сказать статика, но если она ссылается на динамический контент, тогда могут быть неприятности. В таких случаях ссылки определяются как параметры страницы, которые подставляются при выводе. Если страница умерла или изменила адрес, то либо не будет ссылки, либо будет новый адрес. Хотя хозяину виднее.
Ответить с цитированием
  #6 (permalink)  
Старый 19.07.2019, 20:05
Аватар для MC-XOBAHCK
Профессор
Отправить личное сообщение для MC-XOBAHCK Посмотреть профиль Найти все сообщения от MC-XOBAHCK
 
Регистрация: 06.08.2017
Сообщений: 473

У меня эта страница по ссылке уже два дня в браузере открыта. У меня практики нет, поэтому я теряюсь в документации. Написать запрос самостоятельно я не могу.

Почему мне это надо? Если раньше с относительными путями без слеша в начале работало всё нормально, то с переездом если нет вначале слеша, то к пути добавляется вначало путь просматриваемой страницы. В общем вся внутренняя перелинковка на сайте падает, а 404-ая становится самой популярной.
Ответить с цитированием
  #7 (permalink)  
Старый 19.07.2019, 20:19
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,989

Так что у вас в ссылках - только относительные пути или же есть и абсолютные?

PS. Учтите, что MySQL может найти запись по рег. выражению, заменять же им он не может, то есть без костыля тут никак не обойтись. Почему я и говорил об однократном запуске простого скрипта - получили записи, заменили посредством РНР, сохранили.

Последний раз редактировалось laimas, 19.07.2019 в 20:31.
Ответить с цитированием
  #8 (permalink)  
Старый 19.07.2019, 20:37
Аватар для MC-XOBAHCK
Профессор
Отправить личное сообщение для MC-XOBAHCK Посмотреть профиль Найти все сообщения от MC-XOBAHCK
 
Регистрация: 06.08.2017
Сообщений: 473

Есть относительные такого вида без слеша:
<a href="forum/server>Серверные языки и технологии</a>


Есть со слешем:
<a href="/forum/server>Серверные языки и технологии</a>


Есть с полными путями (они на внешние ресурсы):
<a href="https://javascript.ru/forum/server>Серверные языки и технологии</a>



Относительные без слеша в начале ломаются. Нужно им проставить слеш, с учётом что есть и два других вида ссылок которые не нужно менять.
Ответить с цитированием
  #9 (permalink)  
Старый 19.07.2019, 21:06
Профессор
Отправить личное сообщение для laimas Посмотреть профиль Найти все сообщения от laimas
 
Регистрация: 14.01.2015
Сообщений: 12,989

Написать простенький скрипт, который запустить один раз не проблема? В нем запрос - получить все всех записей (объем таблицы позволит?), затем обходом готовим массив, заменяя в нужном поле ссылки:

$s = preg_replace ('/href="(?!\/|https?)/m', 'href="/', $s);


где $s, это значение этого поля.

Затем очищаем таблицу (TRUNCATE), после чего многострочной вставкой заносим массив с изменениями. Можно, конечно, в цикле и обновлять только одно значение полученное запросом, но это более накладная операция.
Ответить с цитированием
  #10 (permalink)  
Старый 19.07.2019, 21:44
Аватар для MC-XOBAHCK
Профессор
Отправить личное сообщение для MC-XOBAHCK Посмотреть профиль Найти все сообщения от MC-XOBAHCK
 
Регистрация: 06.08.2017
Сообщений: 473

laimas, Спасибо!
Я идею понял. В ларавеле там с запросами не сложно. Буду пробовать.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как написать mysql запрос в javascript? Timur85 AJAX и COMET 69 13.08.2020 06:48
MySQL запрос INSERT INTO allonemoon Серверные языки и технологии 1 02.05.2017 05:30
Двойной запрос mysql Mateus Серверные языки и технологии 13 18.03.2016 12:36
Запрос не выбирает MAX дату в MySql базке bugagawenka AJAX и COMET 3 23.10.2014 16:26
Правильный запрос Mysql posta Серверные языки и технологии 1 22.11.2011 00:27