Como usar SUBSTRING usando REGEXP no MySQL

14

Eu tenho a seguinte situação. Eu tenho que substring expressão regular da descrição usando o MySQL. Descrição:

Lorem D9801 ipsum dolor sit amet

Onde D9801 é REGEXP. Toda descrição de texto forte tem conteúdo diferente, mas meu regexp deve se parecer com: REGEXP 'D [[: digit:]] {4}'

REGEXP sempre tem "D" no início e "xxxx" - 4 dígitos no final: Dxxxx

Eu sei que o REGEXP retorna apenas valor verdadeiro / falso, mas como posso fazer uma consulta para retornar apenas o valor 'D9801'?

Eu tentei algo assim:

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

Eu sei que está errado, então eu tento com isso:

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;

Mas como encontrar a posição do regexp?

Ouvi falar em UDF, mas não posso usá-lo, uso hospedagem OVH.

Marek Andrzejak
fonte
Este é basicamente um dup de: stackoverflow.com/questions/4021507/...
Nathan Feger
Sem usar um UDF que não há é construído em termos de funcionalidade para recuperar o padrão combinado da função REGEXP e os outros métodos de correspondência de contar com sabendo a cadeia completa você está combinando para o qual não funciona nesta situação
Payload

Respostas:

3

Isso precisaria usar a sintaxe LOCATEe SUBSTRINGpara obter as informações da string. A sintaxe básica de localização que você precisa é explicada aqui .

LOCATE (pesquisa str, str, [posição])

search str = Uma string que será pesquisada.

str = Uma string que será pesquisada.

position (opcional) = Posição de onde (dentro do segundo argumento) a pesquisa será iniciada.

Enquanto a função de substring necessária é explicada aqui

SUBSTRING (str, pos, len)

str = uma string.

pos = posição inicial.

len = Comprimento em caracteres.

A maneira mais fácil de visualizar isso é pensar em substring como a seguinte SUBSTRING (str FROM pos FOR len)

A sintaxe que eu usei para obter a segunda palavra está abaixo, aproveitei os espaços que estão constantemente ao redor da segunda palavra que você está tentando extrair.

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

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

Infelizmente, a função de expressão regular do MySQL retorna true, false ou null, dependendo da expressão existir ou não.

O truque para efetuar o comportamento desejado é determinar qual substring começa com o caractere de seu interesse, tem o tamanho correto e é seguido por um número. Uma série de funções substring_index são usadas para extrair a string ...

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
fonte