Tengo una gran base de datos que contiene registros que tienen etiquetas <a>
en ellas y me gustaría eliminarlas. Por supuesto, existe el método donde creo un script PHP que selecciona todo, usa strip_tags
y actualiza la base de datos, pero esto lleva mucho tiempo. Entonces, ¿cómo puedo hacer esto con una simple (o complicada) consulta MySQL?¿Cuál es el equivalente de consulta MySQL de PHP strip_tags?
Respuesta
No creo que haya ninguna forma eficiente de hacerlo en MySQL solo.
MySQL tiene una función REPLACE()
, pero solo puede reemplazar cadenas constantes, no patrones. Posiblemente podría escribir una función almacenada en MySQL para buscar y reemplazar etiquetas, pero en ese punto probablemente sea mejor que escriba un script PHP para hacer el trabajo. Puede que no sea bastante tan rápido, pero probablemente será más rápido de escribir.
REPLACE()
funciona bastante bien.
El acercamiento sutil:
REPLACE(REPLACE(node.body,'<p>',''),'</p>','') as `post_content`
... y el no tan sutil: (conversión de cadenas en las babosas)
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`
Aquí van:
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;
hice Asegúrese de que elimine los corchetes de apertura no coincidentes porque son peligrosos, aunque ignora los corchetes de cierre no emparejados porque son inofensivos.
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
no funcionó para mí; MySQL dijeron: Documentación # 1064 - Usted tiene un error en su sintaxis SQL, consulte el manual que corresponde a su versión del servidor MySQL para la sintaxis correcta al uso cerca '' en la línea 3 – mahen3d
'delimitador // CREATE strip_tags función ($ texto str) Retorna el texto COMENZAR DECLARE $ inicio, final INT DEFAULT $ 1; BUCLE SET $ = inicio LOCALIZAR ("<", $ str, $ start); IF (! $ Start) ENTONCES RETORNO $ str; TERMINARA SI; SET $ end = LOCATE (">", $ str, $ start); IF (! $ End) LUEGO SET $ end = $ start; TERMINARA SI; SET $ str = INSERT ($ str, $ start, $ end - $ start + 1, ""); END LOOP; END // delimitador; ' – nzn
DROP FUNCTION if EXISTS strip_tags; DELIMITER | CREAR FUNCIÓN strip_tags (texto $ str) DEVOLUCIONES texto COMIENZO DECLARAR $ start, $ end INT DEFAULT 1; LOOP SET $ start = LOCATE ("<", $ str, $ start); IF (! $ Start) ENTONCES RETORNO $ str; TERMINARA SI; SET $ end = LOCATE (">", $ str, $ start); IF (! $ End) LUEGO SET $ end = $ start; TERMINARA SI; SET $ str = INSERT ($ str, $ start, $ end - $ start + 1, ""); END LOOP; END; | DELIMITER; – IRvanFauziE
Estoy transmitiendo este código, parece muy similar al anterior. Trabajó para mí, espero que ayude.
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
Hice un pequeño punto de referencia aproximado en 5000 (~ 20mb) varias muestras de texto sin formato/html (descripciones de trabajo raspado). La salida de su ejemplo es exactamente la misma que la de Boann, sin embargo su código tomó ~ 32s para procesar y Boann solo 7s haciendo ** la solución de Boann 4.5x más rápida **. Solo estoy poniendo esto aquí para futuras referencias si alguien enfrenta el mismo dilema que yo. Gracias a ambos, chicos. –
Boann's funciona una vez que haya agregado SET $str = COALESCE($str, '');
.
de esta post:
también tomar nota, es posible que desee poner un SET $ cadena = COALESCE ($ cadena, ''); justo antes del bucle; de lo contrario, los valores nulos pueden provocar una consulta final interrumpe/nunca . - Tom C17 de agosto a las 9:51
estoy usando la biblioteca lib_mysqludf_preg para esto y una expresión regular como esto:
SELECT PREG_REPLACE('#<[^>]+>#',' ',cell) FROM table;
también lo hizo así por filas, que con las entidades HTML codificados:
SELECT PREG_REPLACE('#<.+?>#',' ',cell) FROM table;
Probablemente hay casos en que estos pueden fallar pero no he encontrado ninguno y son razonablemente rápidos.
Acabo de ampliar la respuesta @boann para permitir la orientación de cualquier etiqueta específica para que podamos reemplazar las etiquetas una por una con cada llamada a la función. Solo necesita pasar el parámetro de etiqueta, p. 'a'
para reemplazar todas las etiquetas de anclaje de apertura/cierre. Esto responde a la pregunta formulada por OP, a diferencia de la respuesta aceptada, que elimina TODAS las etiquetas.
# 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. Python es equivalente a strip_tags de PHP?
- 2. ¿cuál es la consulta equivalente en mysql?
- 3. ¿Cuál es el equivalente a 'ir' en MySQL?
- 4. ¿Cuál es el equivalente de REGEXP_SUBSTR en mysql?
- 5. ¿Cuál es el equivalente de java.sql.Types para MySQL TEXT?
- 6. ¿Cuál es el equivalente de InfiniteIterator de PHP en .NET?
- 7. ¿Cuál es el equivalente de C# al "self ::" de PHP?
- 8. ¿Cuál es el equivalente de Perl a print_r() de PHP?
- 9. ¿Cuál es el equivalente de la preg_quote de PHP?
- 10. ¿Cuál es el equivalente en Perl de $ _SERVER de PHP [...]?
- 11. ¿Cuál es el equivalente .NET de PHP var_dump?
- 12. ¿Cuál es el equivalente Java de PHP var_dump?
- 13. ¿Cuál es el equivalente del encodeURIcomponent de JavaScript en PHP?
- 14. ¿Cuál es el ASP.Net equivalente al eco de PHP?
- 15. ¿Cuál es el equivalente de php time() en mssql?
- 16. ¿Cuál es el equivalente de T-SQL de la sintaxis de MySQL LIMIT x, y?
- 17. ¿Cuál es el ASP.NET equivalente a memcached en PHP?
- 18. ¿Cuál es el JSP equivalente a json_encode (en PHP)?
- 19. ¿Cuál es el facebook PHP sdk equivalente a FB.getLoginStatus?
- 20. MySQL IFNULL equivalente para php
- 21. ¿Cuál es el equivalente Ruby de "pythonic"?
- 22. ¿Cuál es el equivalente Python de Tomcat?
- 23. ¿Cuál es el equivalente Monotouch de dealloc?
- 24. ¿Cuál es el equivalente de argv [0]?
- 25. Problema al usar strip_tags en php
- 26. ¿Cuál es el equivalente de SQL Server de INET_ATON
- 27. ¿Por qué no funciona strip_tags en PHP?
- 28. ¿Cuál es el equivalente de InnoDB del key_buffer_size de MyISAM?
- 29. ¿Cuál es el equivalente de Ruby de preg_quote()?
- 30. ¿Cuál es el equivalente de 'SHOW PROCESSLIST' de mysql en el servidor SQL?
sí, probablemente estás justo :( – faq