我有一个大型数据库,其中包含有<a>
标签的记录,我想删除它们。当然,有一种方法可以创建一个全选的PHP脚本,使用strip_tags
并更新数据库,但这需要很长时间。那么我怎样才能用一个简单的(或复杂的)MySQL查询来做到这一点呢?什么是PHP strip_tags的MySQL查询等价物?
回答
我不相信有任何有效的方法可以在MySQL中单独执行此操作。
MySQL确实有一个REPLACE()
函数,但它只能替换常量字符串,而不是模式。你可能会写一个MySQL存储函数来搜索和替换标签,但是在那时你可能最好写一个PHP脚本来完成这项工作。它可能不是相当尽快,但它可能会写得更快。
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`
在这里你去:
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
,我没有工作,MySQL表示:文件 #1064 - 你在你的SQL语法错误;检查对应于您的MySQL服务器版本正确的语法手册使用近 '' 在行3 – mahen3d
'分隔符// CREATE FUNCTION用strip_tags($ STR text)返回文本 BEGIN DECLARE $开始,$端INT DEFAULT 1; LOOP SET $开始= LOCATE (“<”,$ str,$ start); IF(!$ start)THEN RETURN $ str;万一; SET $ end = LOCATE(“>”,$ str,$ start); IF(!$ end)THEN SET $ end = $ start;万一; SET $ str = INSERT($ str,$ start,$ end - $ start + 1,“”); END LOOP; END // 定界符;' – nzn
DROP FUNCTION IF EXISTS strip_tags; DELIMITER | CREATE FUNCTION strip_tags($ str text)返回文本 BEGIN DECLARE $ start,$ end INT DEFAULT 1;设置$ start = LOCATE(“<”,$ str,$ start); IF(!$ start)THEN RETURN $ str;万一; SET $ end = LOCATE(“>”,$ str,$ start); IF(!$ end)THEN SET $ end = $ start;万一; SET $ str = INSERT($ str,$ start,$ end - $ start + 1,“”); END LOOP; END; | DELIMITER; – IRvanFauziE
我正在传递这段代码,看起来与上面非常相似。为我工作,希望它有帮助。
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
我对5000(〜20mb)的各种纯文本/ html样本(刮掉的工作描述)做了一个小的粗略基准。你的例子的输出和Boann的完全一样,但是你的代码花费了大约32s来处理,而Boann的7s使得Boann的解决方案快了4.5倍**。如果有人会像我一样面对同样的困境,我只是把它放在这里供将来参考。感谢你们两位。 –
Boann的作品一旦我加入SET $str = COALESCE($str, '');
。
从这个post:
另外要注意,你可以把它放到一个SET $海峡= COALESCE($海峡, ''); 就在循环之前,否则空值可能导致崩溃/从不 结束查询。汤姆 - ç8月17日在9:51
我使用lib_mysqludf_preg库这一点,这样的正则表达式:
SELECT PREG_REPLACE('#<[^>]+>#',' ',cell) FROM table;
也没有像这样的行与编码的HTML实体:
SELECT PREG_REPLACE('#<.+?>#',' ',cell) FROM table;
可能有些情况下,这些可能会失败,但我没有遇到任何问题,他们相当快。
我刚刚扩展了答案@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');
- 1. MySQL中'go'的等价物是什么?
- 2. 什么是PostgreSQL'schema'的MySQL等价物?
- 3. 什么是PHP的preg_quote的等价物?
- 4. 什么是PHP var_dump的.NET等价物?
- 5. 什么是PHP $ _ENV的Ruby等价物?
- 6. 什么是PHP flush()的Java等价物?
- 7. .net 3.5中的这个查询的等价物是什么?
- 8. PHP的mysql等价物mysql_real_escape_string()
- 9. 什么是这个SQL查询的Django等价物?
- 10. mongoid3中这个mongoid2查询的等价物是什么?
- 11. 什么是这个Linq查询的lambda等价物?
- 12. 什么是以下SQL查询的LINQ等价物?
- 13. laravel的等价查询是什么?
- 14. 什么是PHP的proc_open(),proc_close()等Perl的等价物?
- 15. 什么是Python的os.walk的等价物?
- 16. MessageFormat的Pattern.quote()的等价物是什么?
- 17. 在php中有什么等价物?
- 18. 什么是Win32_OperatingSystem的64位等价物?
- 19. 什么是VC7中的strtok_s等价物?
- 20. java.time.Duration的Android等价物是什么?
- 21. 什么是“hasOwnProperty()”接口的等价物?
- 22. 什么是JQuery .load()的YUI等价物?
- 23. InputBindings的WinRT等价物是什么?
- 24. 什么是Silverlight中的OnRender等价物?
- 25. C#中TreeBidiMap的等价物是什么?
- 26. 什么是mac的win32等价物?
- 27. 什么是C#中的vbNullChar等价物?
- 28. 什么是ChrW(e.KeyCode)的C#等价物?
- 29. 什么是request.getRemoteUser()的JSP EL等价物?
- 30. 什么是JMX的.NET等价物?
是可能你是正确的:( – faq