从记录中删除HTML标记

Sub*_*bha 24 mysql

需要帮助从具有下面内容的表一列形成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%' "
Run Code Online (Sandbox Code Playgroud)

我会得到所有4行,但结果是错误的.我需要得到正确的输出只有第3行.这一行只有内容中的mytext所有其他内容的原因不在于内容,而是mytext在所有行中

如何编写MySQL查询?

KB.*_*KB. 43

尝试这个解决方案:不是自己尝试,但显然它有效.

来源: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>');
Run Code Online (Sandbox Code Playgroud)

  • 如果使用此功能,请记住将Dirty varchar增加到一个较高的值,我选择1000000对我的项目来说是安全的. (2认同)
  • 请记住,您可能需要为返回值设置字符集,否则MySQL会将字符串强制转换为其默认字符集,并且可能会丢失一些数据。返回varchar(4000)CHARSET utf8 (2认同)

Boa*_*ann 23

这是我对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;
Run Code Online (Sandbox Code Playgroud)

我确保它删除了不匹配的开括号,因为它们很危险,但它忽略了任何不成对的右括号,因为它们是无害的.

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
Run Code Online (Sandbox Code Playgroud)

请享用.

  • 另外需要注意的是,您可能希望在循环之前放置一个`SET $ str = COALESCE($ str,'');`否则空值可能会导致崩溃/永不结束的查询. (6认同)

Rya*_* Ou 12

如果您的内容始终以标签开头(<body>等)

试试这个:

SELECT * from table  WHERE colmn_name REGEXP  '>[^<]*mytext';
Run Code Online (Sandbox Code Playgroud)


小智 6

这里需要正则表达式匹配,带有否定的前瞻断言:“mytext”后面没有结束标记。从 8.0 开始,MySQL 仍然不支持外观断言,但 MariaDB 支持。MariaDB 查询问题:

SELECT * FROM table WHERE column_name REGEXP 'mytext(?![^<>]*>)';
Run Code Online (Sandbox Code Playgroud)

该问题的另一个解决方案是在匹配之前删除一些/所有标签。与 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%';
Run Code Online (Sandbox Code Playgroud)

除此之外,问题中的字符串混合了数据和表示。不应定期搜索它们,因为这会浪费系统资源。


Ego*_*hin -3

您无法在 SQL 查询中解析 HTML,这没有任何意义。也许您可以只维护表的特殊搜索版本,并删除所有 HTML,但您必须使用一些外部处理来做到这一点。