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