web-dev-qa-db-ja.com

PHP strip_tags)に相当するMySQLクエリは何ですか?

<a>タグが含まれているレコードを含む大規模なデータベースがあり、それらを削除したいと考えています。もちろん、PHPすべてを選択し、strip_tagsを使用してデータベースを更新するスクリプトを作成する方法もありますが、これには長い時間がかかります。単純な(または複雑な)MySQLクエリ?

21
faq

MySQLだけでこれを行う効率的な方法はないと思います。

MySQLにはREPLACE()関数がありますが、パターンではなく定数文字列のみを置き換えることができます。タグを検索して置換するためのMySQLストアドファンクションを作成することもできますが、その時点でPHPスクリプトを作成してジョブを実行する方がよいでしょう。そうでない場合もありますかなりと同じくらい速いですが、おそらく書く方が速いでしょう。

6

どうぞ:

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
22
Boann

MySQL> = 5.5は、問題を解決するためのXML関数を提供します。

SELECT ExtractValue(field, '//text()') FROM table;

リファレンス: https://dev.mysql.com/doc/refman/5.5/en/xml-functions.html

12
Marco Marsala

私はこのコードを渡していますが、上記と非常に似ています。私のために働いた、それが役に立てば幸い。

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
5
phenicie

@boannの回答を拡張して特定のタグをターゲティングできるようにしたので、各関数呼び出しでタグを1つずつ置き換えることができます。タグパラメータを渡すだけです。 '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
ajmedway

SET $str = COALESCE($str, '');を追加すると、Boannが機能します。

これから post

また、SET $ str = COALESCE($ str、 '');を設定することもできます。ループの直前、それ以外の場合はnull値が原因で、クエリがクラッシュするか、終了しない場合があります。 –トムC 8月17日9:51

1
Scott2B

これに lib_mysqludf_preg ライブラリを使用しており、次のような正規表現を使用しています。

SELECT PREG_REPLACE('#<[^>]+>#',' ',cell) FROM table;

エンコードされたhtmlエンティティを含む行についても、次のようにしました。

SELECT PREG_REPLACE('#&lt;.+?&gt;#',' ',cell) FROM table;

おそらくこれらが失敗するかもしれませんが、私はこれまで遭遇したことがなく、かなり高速です。

1
billynoah

MySQL 8以降およびMariaDB 10.0.5以降と互換性があります。

SELECT REGEXP_REPLACE(body、 '<[^>] *> +'、 '')FROM app_cms_sections

0
Gene Kelly