<a>
タグが含まれているレコードを含む大規模なデータベースがあり、それらを削除したいと考えています。もちろん、PHPすべてを選択し、strip_tags
を使用してデータベースを更新するスクリプトを作成する方法もありますが、これには長い時間がかかります。単純な(または複雑な)MySQLクエリ?
MySQLだけでこれを行う効率的な方法はないと思います。
MySQLにはREPLACE()
関数がありますが、パターンではなく定数文字列のみを置き換えることができます。タグを検索して置換するためのMySQLストアドファンクションを作成することもできますが、その時点でPHPスクリプトを作成してジョブを実行する方がよいでしょう。そうでない場合もありますかなりと同じくらい速いですが、おそらく書く方が速いでしょう。
どうぞ:
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> = 5.5は、問題を解決するためのXML関数を提供します。
SELECT ExtractValue(field, '//text()') FROM table;
リファレンス: https://dev.mysql.com/doc/refman/5.5/en/xml-functions.html
私はこのコードを渡していますが、上記と非常に似ています。私のために働いた、それが役に立てば幸い。
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
@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');
SET $str = COALESCE($str, '');
を追加すると、Boannが機能します。
これから post :
また、SET $ str = COALESCE($ str、 '');を設定することもできます。ループの直前、それ以外の場合はnull値が原因で、クエリがクラッシュするか、終了しない場合があります。 –トムC 8月17日9:51
これに lib_mysqludf_preg ライブラリを使用しており、次のような正規表現を使用しています。
SELECT PREG_REPLACE('#<[^>]+>#',' ',cell) FROM table;
エンコードされたhtmlエンティティを含む行についても、次のようにしました。
SELECT PREG_REPLACE('#<.+?>#',' ',cell) FROM table;
おそらくこれらが失敗するかもしれませんが、私はこれまで遭遇したことがなく、かなり高速です。
MySQL 8以降およびMariaDB 10.0.5以降と互換性があります。
SELECT REGEXP_REPLACE(body、 '<[^>] *> +'、 '')FROM app_cms_sections