|
|
|
| Моих познаний не хватает, поиском ответ найти не могу, т.к. толком не знаю что искать. Прошу помощи.
Задача распространенная, в то же время решения не нашел: в таблице лежат статьи блога, в которых могут содержаться внешние и внутренние ссылки (а могут и не содержаться, а могут быть и те, и другие в одной статье).
Нужно: выбрать из таблицы все записи, где нет ни одной внешней ссылки, в то время как внутренние ссылки (начинающиеся с http://my-site) могут присутствовать сколько угодно.
Помогите, пожалуйста. | |
|
|
|
|
|
|
|
для: pojar
(04.07.2013 в 17:32)
| | Ссылки в таблице как хранятся?
Вернее с одной все понятно - VARCHAR со ссылкой
А если несколько ссылок, то как?
Пример данных покажите | |
|
|
|
|
|
|
|
для: Sfinks
(04.07.2013 в 18:32)
| | Ссылки в тексте статей попадаются в виде <a href="http://site.ru">всяких ссылок</a> прямо среди абзацев. | |
|
|
|
|
|
|
|
для: pojar
(04.07.2013 в 22:53)
| | Это очень плохо для скорости.
Запрос конечно можно составить, но если статей много, запрос будет очень медленный.
Есть какой-то список сторонних доменов, которые могут встречаться в ссылках?
Допустим:
http://domen1.ru
http://domen2.ru
http://domen3.ru
Запрос будет таким:
SELECT *
FROM tbl
WHERE NOT txt REGEXP 'http:\/\/(domen1\.ru|domen2\.ru|domen3\.ru)'
|
| |
|
|
|
|
|
|
|
для: Sfinks
(04.07.2013 в 23:29)
| | В том и дело, что списка нет и ссылки могут быть любыми. Но в то же время скорость запроса значения не имеет, он будет выполняться вручную один раз от случая к случаю. | |
|
|
|
|
|
|
|
для: pojar
(05.07.2013 в 01:34)
| | Если списка нет, то врядли вы что-то сделаете на уровне MySQL.
Просто в MySQL довольно урезанная версия регулярных выражений. Просмотры вперед/назад не поддерживаются.
Если это нужно для служебного функционала, то выбирайте все записи и проверяйте в PHP.
Уменьшить количество, можно отсеяв те, в которых нет ни одной ссылки.
SELECT * FROM tbl WHERE fld LIKE '%http:%'
|
И заведите хотя бы еще одно поле, в котором будет флаг проверена запись или нет, чтобы не проверять несколько раз.
А еще лучше, на будущее, добавить поле, в котором будет целочисленный флаг, показывающий какие ссылки есть в статье:
0 - ни каких
1 - локальные
2 - внешние
3 - и те и те
|
Также можно сделать это поле типом SET.
И заполняйте его при сохранении записи, проводя анализ в PHP. | |
|
|
|
|
|
|
|
для: Sfinks
(05.07.2013 в 08:33)
| | Такие решения для меня очевидны, но они не подходят. | |
|
|
|
|
|
|
|
для: pojar
(05.07.2013 в 09:09)
| | Других в MySQL нет | |
|
|
|
|
|
|
|
для: Sfinks
(04.07.2013 в 23:29)
| | Попробовал написать так
SELECT *
FROM tbl
WHERE NOT txt REGEXP 'http://[a-r,t-z]{1}'
|
Предполагается, что мой сайт http://site.ru, и мы ищем записи в которых нет ссылок на домены начинающиеся на любые буквы, кроме 's'. Получаем практически то что нужно, только изредка проскакивают ссылки на сайты с буквой 's' вначале вроде http://superportal.ru. Задача решена не полностью, но это всяк лучше, чем просматривать вручную или чем "нет никакого решения и быть не может".
Помогите дописать дальше регулярку. С первой буквой у меня получилось, а когда пытаюсь вторую и следующие таким же образом дописать, то что-то не срабатывает и находит много лишнего. | |
|
|
|
|
|
|
|
для: pojar
(05.07.2013 в 19:08)
| | > то что-то не срабатывает и находит много лишнего
Потому что, я вам сразу сказал, для этого нужна хотя бы поддержка просмотра вперед, а ее в MySQL нет.
Ну ладно, раз вам так хочется, пожалуйста:
SELECT *
FROM tbl
WHERE NOT txt REGEXP 'http://[a-rt-z]
AND NOT txt REGEXP 'http://.[a-hj-z]
AND NOT txt REGEXP 'http://..[a-su-z]
AND NOT txt REGEXP 'http://...[a-df-z]
-- ну и так далее
|
Остается только надеяться, что у вас не 40 знаков в домене | |
|
|
|
|
|
|
|
для: Sfinks
(05.07.2013 в 22:16)
| | Отлично! Это то что нужно. В домене всего 4 символа. Работает!
Очень вам благодарен, низкий поклон. | |
|
|
|
|
|
|
|
для: pojar
(05.07.2013 в 19:08)
| | > но это всяк лучше, чем "нет никакого решения и быть не может".
А кто вам говорил про нет решения?
Лучшее решение в этом случае - перебрать в ПХП.
И соответствующий скрипт пишется 10 минут - это максимум!
А вы не первый день решение ишете. | |
|
|
|
|
|
|
|
для: Sfinks
(05.07.2013 в 22:31)
| | Сейчас вот нашел, но еще не пробовал:
SELECT * FROM `tbl` WHERE LOCATE(`field`, 's') = 0
|
LOCATE ищет в строке или поле `field` подстроку s. Если подстрока найдена - возвращает индекс первого символа подстроки в строке. Если не найдена - возвращает 0 (нумерация символов с строках в MySQL начинается с 1). | |
|
|
|