Удалить теги HTML из записи
Нужна помощь в формировании запроса MYSQL
из таблицы один столбец, имеющий нижеприведенный контент
Row1 : this is first <a href='mytext.txt'>row</a> from the table
Row 2 : THis is the second row <img src ='mytext.jpg'> my image is there
Row 3 : <p>This is the Third row my mytext is there </p>
Row 4 : <p class='te_mytext'>This is the Third row my text is there </p>
это строки таблицы. Я пытаюсь найти ключевое слово как "mytext"
мой запрос
SELECT * from table WHERE colmn_name ` like '%mytext%' "
Я получу все 4 строки в результате, но результат неверен. Мне нужно получить правильный вывод, как только Row 3. Причина, по которой эта строка содержит только mytext внутри содержимого, не является содержимым, но mytext имеет все строки
Как я могу написать запрос MySQL?
Ответы
Ответ 1
попробуйте это решение: не пробовал сам, но, по-видимому, он работает.
источник: http://forums.mysql.com/read.php?52,177343,177985#msg-177985
SET GLOBAL log_bin_trust_function_creators=1;
DROP FUNCTION IF EXISTS fnStripTags;
DELIMITER |
CREATE FUNCTION fnStripTags( Dirty varchar(4000) )
RETURNS varchar(4000)
DETERMINISTIC
BEGIN
DECLARE iStart, iEnd, iLength int;
WHILE Locate( '<', Dirty ) > 0 And Locate( '>', Dirty, Locate( '<', Dirty )) > 0 DO
BEGIN
SET iStart = Locate( '<', Dirty ), iEnd = Locate( '>', Dirty, Locate('<', Dirty ));
SET iLength = ( iEnd - iStart) + 1;
IF iLength > 0 THEN
BEGIN
SET Dirty = Insert( Dirty, iStart, iLength, '');
END;
END IF;
END;
END WHILE;
RETURN Dirty;
END;
|
DELIMITER ;
SELECT fnStripTags('this <html>is <b>a test</b>, nothing more</html>');
Ответ 2
Здесь моя реализация функции strip_tags:
CREATE FUNCTION `strip_tags`($str text) RETURNS text
BEGIN
DECLARE $start, $end INT DEFAULT 1;
LOOP
SET $start = LOCATE("<", $str, $start);
IF (!$start) THEN RETURN $str; END IF;
SET $end = LOCATE(">", $str, $start);
IF (!$end) THEN SET $end = $start; END IF;
SET $str = INSERT($str, $start, $end - $start + 1, "");
END LOOP;
END;
Я убедился, что он удаляет несогласованные открывающие скобки, потому что они опасны, хотя игнорирует любые непарные закрывающие скобки, потому что они безвредны.
mysql> select strip_tags('<span>hel<b>lo <a href="world">wo<>rld</a> <<x>again<.');
+----------------------------------------------------------------------+
| strip_tags('<span>hel<b>lo <a href="world">wo<>rld</a> <<x>again<.') |
+----------------------------------------------------------------------+
| hello world again. |
+----------------------------------------------------------------------+
1 row in set
Enjoy.
Ответ 3
Если ваш контент всегда начинается с тегов (<body> и т.д.)
попробуйте следующее:
SELECT * from table WHERE colmn_name REGEXP '>[^<]*mytext';
Ответ 4
Добавьте эти строки в функцию fnStripTags
после SET Dirty = Insert( Dirty, iStart, iLength, '');
set Dirty = Replace(Dirty,' ',''); #No space between & and nbsp;
set Dirty = Replace(Dirty,'\r','');
set Dirty = Replace(Dirty,'\n','');
Ответ 5
Я использовал strip_tags() выше (спасибо Boann) с небольшим модом, чтобы избавиться от html-кодов ударных символов и т.д. Так вот:
...BEGIN
DECLARE $start, $end INT DEFAULT 1;
SET $str = REPLACE($str, " ", " ");
SET $str = REPLACE($str, "€", "€");
SET $str = REPLACE($str, "á", "á");
SET $str = REPLACE($str, "é", "é");
SET $str = REPLACE($str, "í", "í");
SET $str = REPLACE($str, "ó", "ó");
SET $str = REPLACE($str, "ú", "ú");
LOOP...
Ответ 6
Реализация битов в MySQL, позволяющая настраивать таргетинг на определенный тег, чтобы мы могли заменять теги один за другим при каждом вызове функции. Вам просто нужно передать параметр тега, например. 'a'
, чтобы заменить все открывающие/закрывающие якорные метки.
# MySQL function to programmatically replace out specified html tags from text/html fields
# run this to drop/update the stored function
DROP FUNCTION IF EXISTS `strip_tags`;
DELIMITER |
# function to nuke all opening and closing tags of type specified in argument 2
CREATE FUNCTION `strip_tags`($str text, $tag text) RETURNS text
BEGIN
DECLARE $start, $end INT DEFAULT 1;
SET $str = COALESCE($str, '');
LOOP
SET $start = LOCATE(CONCAT('<', $tag), $str, $start);
IF (!$start) THEN RETURN $str; END IF;
SET $end = LOCATE('>', $str, $start);
IF (!$end) THEN SET $end = $start; END IF;
SET $str = INSERT($str, $start, $end - $start + 1, '');
SET $str = REPLACE($str, CONCAT('</', $tag, '>'), '');
END LOOP;
END;
| DELIMITER ;
# test select to nuke all opening <a> tags
SELECT
STRIP_TAGS(description, 'a') AS stripped
FROM
tmpcat;
# run update query to replace out all <a> tags
UPDATE tmpcat
SET
description = STRIP_TAGS(description, 'a');
Ответ 7
Здесь требуется регулярное выражение, с отрицательным ожиданием: "mytext", за которым не следует закрывающий тег. MySQL по-прежнему, начиная с 8.0, не поддерживает утверждения look, но MariaDB делает. Запрос MariaDB на вопрос:
SELECT * FROM table WHERE column_name REGEXP 'mytext(?![^<>]*>)';
Другое решение для этого вопроса - удалить некоторые/все теги перед сопоставлением. Это неэффективно, по сравнению с REGEXP, но и работает. В MySQL, начиная с 8.0 и MariaDB, начиная с 10.0.5, есть встроенная функция REGEXP_REPLACE
. "strip_html" - это даже первый пример на странице документации MariaDB. Запрос MySQL/MariaDB для такого подхода:
SELECT * FROM table WHERE REGEXP_REPLACE (column_name, '<.+?>', '') LIKE '%mytext%';
Кроме того, строки в вопросе смешивают данные и представление. Их не следует регулярно искать, так как это пустая трата системных ресурсов.
Ответ 8
Расширена функция strip_tags, предоставленная Boann. Теперь он может использоваться для сохранения или игнорирования фразы между тегами. Обратите внимание на ошибку с пустыми тегами в моей части кода, т.е. для $ keep_phrase = false.
CREATE FUNCTION strip_tags($str text, $tag text,$keep_phrase bool) RETURNS text
BEGIN
DECLARE $start, $end INT DEFAULT 1;
SET $str = COALESCE($str, '');
LOOP
SET $start = LOCATE(CONCAT('<', $tag), $str, $start);
IF (!$start) THEN RETURN $str; END IF;
IF ($keep_phrase) THEN
SET $end = LOCATE('>', $str, $start);
IF (!$end) THEN SET $end = $start; END IF;
SET $str = INSERT($str, $start, $end - $start + 1, '');
SET $str = REPLACE($str, CONCAT('</', $tag, '>'), '');
ELSE
SET $end = LOCATE(CONCAT('</', $tag, '>'),$str,$start);
IF (!$end) THEN
SET $end = LOCATE('/>',$str,$start);
SET $str = INSERT($str, $start, $end - $start + 2, '');
ELSE
SET $str = INSERT($str, $start, $end - $start
+ LENGTH(CONCAT('</', $tag, '>')), '');
END IF;
END IF;
END LOOP;
END //
Чтобы доказать функциональность:
SELECT strip_tags('<p>so<span id="x"> very</span> cool</p><p>so<span id="y"> very</span> cool</p>','span',true);
<p>so very cool</p><p>so very cool</p>
SELECT strip_tags('<p>so<span id="x"> very</span> cool</p><p>so<span id="y"> very</span> cool</p>','span',false);
<p>so cool</p><p>so cool</p>
Пустые элементы с $ keep_phrase = false не поддерживаются, см.
SELECT strip_tags('<p>so<span id="x"> very</span> cool</p><span/><p>so<span id="y"> very</span> cool</p>','span',false);
<p>so cool</p> cool</p>
Ответ 9
Вы не можете анализировать HTML внутри SQL-запросов, что не имеет никакого смысла. Возможно, вы могли бы просто сохранить специальную поисковую версию таблицы со всеми фрагментами HTML, но для этого вам придется использовать некоторую внешнюю обработку.