我有一个大型数据库,其中包含其中包含<a>
个标记的记录,我想将其删除。当然有一种方法可以创建一个选择all的PHP脚本,使用strip_tags
并更新数据库,但这需要很长时间。那么如何使用简单(或复杂)的MySQL查询来实现这一目标呢?
答案 0 :(得分:19)
你走了:
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
答案 1 :(得分:6)
我不相信在MySQL中有任何有效的方法可以做到这一点。
MySQL确实有REPLACE()
函数,但它只能替换常量字符串,而不能替换模式。您可以编写一个MySQL存储函数来搜索和替换标记,但此时您最好还是编写一个PHP脚本来完成这项工作。它可能不会完全,但写入可能会更快。
答案 2 :(得分:5)
我正在传递此代码,看起来与上面的内容非常相似。为我工作,希望它有所帮助。
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
答案 3 :(得分:1)
Boann的作品一旦我添加了cell.textLabel.numberOfLines = 0;
cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping;
。
来自post:
另外需要注意的是,你可能想要设置一个SET $ str = COALESCE($ str,''); 就在循环之前,否则空值可能会导致崩溃/从不 结束查询。 - 汤姆C 8月17日9:51
答案 4 :(得分:1)
我正在使用lib_mysqludf_preg库以及这样的正则表达式:
SELECT PREG_REPLACE('#<[^>]+>#',' ',cell) FROM table;
对于带有编码html实体的行也是这样的:
SELECT PREG_REPLACE('#<.+?>#',' ',cell) FROM table;
有些情况下可能会失败,但我没有遇到任何问题,而且他们的速度相当快。
答案 5 :(得分:1)
我只是扩展了答案@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');
答案 6 :(得分:1)
MySQL> = 5.5提供了XML函数来解决您的问题:
SELECT ExtractValue(field, '//text()') FROM table;
参考:https://dev.mysql.com/doc/refman/5.5/en/xml-functions.html
答案 7 :(得分:0)
兼容MySQL 8+和MariaDB 10.0.5 +
SELECT REGEXP_REPLACE(正文,&#39;&lt; [^&gt;] *&gt; +&#39;,&#39;&#39;)FROM app_cms_sections
答案 8 :(得分:-1)
REPLACE()
效果非常好。
微妙的方法:
REPLACE(REPLACE(node.body,'<p>',''),'</p>','') as `post_content`
......并且不那么微妙:(将字符串转换为slug)
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`