Cómo contar palabras en MySQL / regular expression replacer?

¿Cómo puedo, en una consulta MySQL, tener el mismo comportamiento que la función Regex.Replace (por ejemplo, en .NET / C #)?

Lo necesito porque, como muchas personas, me gustaría contar el número de palabras en un campo. Sin embargo, no estoy satisfecho con la siguiente respuesta (dada varias veces en ese sitio):

SELECT LENGTH(name) - LENGTH(REPLACE(name, ' ', '') +1 FROM table 

Porque no da buenos resultados cuando hay más de un espacio entre dos palabras.

Por cierto, creo que la función Regex.Replace puede ser interesante, ¡así que todas las buenas ideas son bienvenidas!

Hay REGEXP_REPLACE disponible como funciones definidas por el usuario de MySQL .

Recuento de palabras: si puede controlar los datos que entran en la base de datos, puede eliminar los espacios en blanco dobles antes de insertarlos. Además, si tiene que acceder al conteo de palabras con frecuencia, puede calcularlo una vez en su código y almacenar el conteo en la base de datos.

ACTUALIZACIÓN: ahora se ha agregado una respuesta separada para MySQL 8.0+ , que se debe usar con preferencia. (Se mantuvo esta respuesta en caso de estar limitado a usar una versión anterior).

Casi un duplicado de esta pregunta, pero esta respuesta abordará el caso de uso de conteo de palabras basado en la versión avanzada del sustituto de expresión regular personalizado de esta publicación de blog .

Manifestación

Demostración en línea de Rextester

Para el texto de muestra, esto da un recuento de 61, el mismo que todos los contadores de palabras en línea que he probado (por ejemplo, https://wordcounter.net/ ).

SQL (excluyendo el código de función por brevedad) :

 SELECT txt, -- Count the number of gaps between words CHAR_LENGTH(txt) - CHAR_LENGTH(reg_replace(txt, '[[:space:]]+', -- Look for a chunk of whitespace '^.', -- Replace the first character from the chunk '', -- Replace with nothing (ie remove the character) TRUE, -- Greedy matching 1, -- Minimum match length 0, -- No maximum match length 1, -- Minimum sub-match length 0 -- No maximum sub-match length )) + 1 -- The word count is 1 more than the number of gaps between words - IF (txt REGEXP '^[[:space:]]', 1, 0) -- Exclude whitespace at the start from count - IF (txt REGEXP '[[:space:]]$', 1, 0) -- Exclude whitespace at the end from count AS `word count` FROM tbl; 

La respuesta es no, no puedes tener el mismo comportamiento en MySQL.

Pero le recomiendo que revise esta pregunta anterior sobre el tema que enlaza con un UDF que supuestamente habilita parte de esta funcionalidad.

MySQL 8.0 ahora proporciona una función decente REGEXP_REPLACE , que hace esto mucho más simple:

SQL

 SELECT -- Count the number of gaps between words CHAR_LENGTH(txt) - CHAR_LENGTH(REGEXP_REPLACE( txt, '[[:space:]]([[:space:]]*)', -- A chunk of one or more whitespace characters '$1')) -- Discard the first whitespace character and retain the rest + 1 -- The word count is 1 more than the number of gaps between words - IF (txt REGEXP '^[[:space:]]', 1, 0) -- Exclude whitespace at the start from count - IF (txt REGEXP '[[:space:]]$', 1, 0) -- Exclude whitespace at the end from count AS `Word count` FROM tbl; 

Manifestación

Demostración en línea DB-Fiddle