Cómo usar SUBSTRING usando REGEXP en MySQL

14

Tengo la siguiente situación. Tengo que subcadenar la expresión regular de la descripción usando MySQL. Descripción:

Lorem D9801 ipsum dolor sit amet

Donde D9801 es REGEXP. Cada descripción de texto fuerte tiene contenido diferente, pero mi expresión regular debería verse así: REGEXP 'D [[: digit:]] {4}'

REGEXP siempre tiene "D" al principio y "xxxx" - 4 dígitos al final: Dxxxx

Sé que REGEXP devuelve solo el valor verdadero / falso, pero ¿cómo puedo hacer que la consulta devuelva solo el valor 'D9801'?

Intenté algo como esto:

SELECT SUBSTRING (description, LOCATE(REGEXP 'D[[:digit:]]{4}', description), 5)
FROM (
   SELECT "Lorem D9801 ipsum dolor sit amet" AS description
) temp

Sé que está mal, así que trato con esto:

SELECT 
    id, 
    SUM(description REGEXP 'D[[:digit:]]{4}') AS matches, 
    CASE
        WHEN (SUM(description REGEXP 'D[[:digit:]]{4}') > 0) THEN 
            SUBSTRING(description, LOCATE( /*POSITION_OF_REGEXP_IN_DESC*/ , description), 5)
        ELSE 'Brak schematu'
    END AS show_substr FROM ps_description GROUP BY id;

Pero, ¿cómo encontrar la posición de regexp?

Escuché sobre UDF pero no puedo usarlo, uso el alojamiento OVH.

Marek Andrzejak
fuente
Esto es básicamente un duplicado de: stackoverflow.com/questions/4021507/…
Nathan Feger
Sin usar un UDF no hay una funcionalidad integrada para recuperar el patrón coincidente de la función REGEXP y los otros métodos de coincidencia dependen de conocer la cadena completa con la que no coincide en esta situación
Carga útil

Respuestas:

3

Esto necesitaría usar la sintaxis LOCATEy SUBSTRINGpara sacar la información de la cadena. Aquí se explica la sintaxis básica de localización que necesitaría .

LOCATE (buscar str, str, [posición])

search str = Una cadena que se buscará.

str = Una cadena que se va a buscar.

position (opcional) = Posición desde donde (dentro del segundo argumento) comenzará la búsqueda.

Si bien la función de subcadena que necesita se explica aquí

SUBSTRING (str, pos, len)

str = una cadena.

pos = posición inicial.

len = longitud en caracteres.

La forma más fácil de ver esto es pensar en la subcadena como la siguiente SUBSTRING (str FROM pos FOR len)

La sintaxis que usé para obtener la segunda palabra está debajo, aproveché los espacios que están constantemente alrededor de la segunda palabra que estás tratando de extraer.

declare @String varchar(50) ='Lorem D9801 ipsum dolor sit amet'

SUBSTRING
(
@String,
LOCATE(' ', @String),
LOCATE(' ', @String, (LOCATE(' ', @String) + 1)) - LOCATE(' ', @String)
)
James Rhoat
fuente
1

Desafortunadamente, la función de expresión regular de MySQL devuelve verdadero, falso o nulo dependiendo de si la expresión existe o no.

El truco para lograr el comportamiento deseado es determinar qué subcadena comienza con el carácter que le interesa, tiene la longitud correcta y le sigue un número. Se utiliza una serie de funciones substring_index para extraer la cadena ...

set @string:='Lorem D9801 ipsum dolor sit amet';
select
case when @string like '% D____ %' and cast((@num:= substring_index(substring_index(@string,concat(substring_index(@string,' D',1),' D'),-1),' ',1)) as signed) between '0' and '9999' then concat('D',@num)
     when @string like '% D% D____ %' and cast((@num:= substring_index(substring_index(@string,concat(substring_index(@string,' D',2),' D'),-1),' ',1)) as signed) between '0' and '9999' then concat('D',@num)
     when @string like '% D% D% D____ %' and cast((@num:= substring_index(substring_index(@string,concat(substring_index(@string,' D',3),' D'),-1),' ',1)) as signed) between '0' and '9999' then concat('D',@num)
     when @string like '% D% D% D% D____ %' and cast((@num:= substring_index(substring_index(@string,concat(substring_index(@string,' D',4),' D'),-1),' ',1)) as signed) between '0' and '9999' then concat('D',@num)
     when @string like '% D% D% D% D% D____ %' and cast((@num:= substring_index(substring_index(@string,concat(substring_index(@string,' D',5),' D'),-1),' ',1)) as signed) between '0' and '9999' then concat('D',@num)
end as test_case;
+-----------+
| test_case |
+-----------+
| D9801     |
+-----------+
1 row in set (0.00 sec)
RMathis
fuente