Что такое эквивалент запроса MySQL для strip_tags?
У меня есть большая база данных, содержащая записи, в которых есть теги <a>
, и я хотел бы удалить их. Конечно, есть метод, в котором я создаю PHP скрипт, который выбирает все, использует strip_tags
и обновляет базу данных, но это занимает много времени. Итак, как я могу сделать это с помощью простого (или сложного) запроса MySQL?
Ответы
Ответ 1
Я не считаю, что есть эффективный способ сделать это только в MySQL.
MySQL имеет функцию REPLACE()
, но она может заменять только постоянные строки, а не шаблоны. Вы могли бы написать хранимую функцию MySQL для поиска и замены тегов, но в этот момент вам, вероятно, лучше написать PHP скрипт, чтобы выполнить эту работу. Это может быть не так быстро, но, вероятно, быстрее писать.
Ответ 2
Здесь вы идете:
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
Ответ 3
Я передаю этот код, кажется очень похожим на выше. Работал для меня, надеюсь, что это поможет.
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
Ответ 4
Boann работает, когда я добавил SET $str = COALESCE($str, '');
.
из этого сообщения :
Также следует отметить, что вы можете поставить SET $str = COALESCE ($ str, ''); как раз перед циклом в противном случае нулевые значения могут привести к сбою/никогда завершение запроса. - Том С 17 августа в 9:51
Ответ 5
Я использую lib_mysqludf_preg для этого и регулярное выражение:
SELECT PREG_REPLACE('#<[^>]+>#',' ',cell) FROM table;
Также ему понравилось это для строк, которые с кодированными объектами html:
SELECT PREG_REPLACE('#<.+?>#',' ',cell) FROM table;
Есть, вероятно, случаи, когда они могут потерпеть неудачу, но я не сталкивался с ними, и они достаточно быстры.
Ответ 6
Я просто расширил ответ @boann, чтобы разрешить таргетинг любого конкретного тега, чтобы мы могли заменять теги один за другим при каждом вызове функции. Вам просто нужно передать параметр тега, например. 'a'
, чтобы заменить все открывающие/закрывающие якорные метки. Это отвечает на вопрос, заданный OP, в отличие от принятого ответа, который удаляет ВСЕ теги.
# 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
REPLACE()
работает очень хорошо.
Тонкий подход:
REPLACE(REPLACE(node.body,'<p>',''),'</p>','') as `post_content`
... и не так тонко: (Преобразование строк в пули)
LOWER(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(TRIM(node.title), ':', ''), 'é', 'e'), ')', ''), '(', ''), ',', ''), '\\', ''), '\/', ''), '\"', ''), '?', ''), '\'', ''), '&', ''), '!', ''), '.', ''), '–', ''), ' ', '-'), '--', '-'), '--', '-'), '’', '')) as `post_name`