web-dev-qa-db-fra.com

Comment utiliser SUBSTRING à l'aide de REGEXP dans MySQL

J'ai la situation suivante. Je dois sous-chaîne l'expression régulière de la description en utilisant MySQL. La description:

Lorem D9801 ipsum dolor assis amet

Où D9801 est REGEXP. Chaque texte fort description a un contenu différent mais mon expression régulière devrait ressembler à: REGEXP 'D [[: digit:]] {4}'

REGEXP a toujours "D" au début et "xxxx" - 4 chiffres à la fin: Dxxxx

Je sais que REGEXP ne renvoie que la valeur vrai/faux, mais comment puis-je faire une requête pour renvoyer uniquement la valeur 'D9801'?

J'ai essayé quelque chose comme ça:

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

Je sais que c'est faux, alors j'essaye avec ceci:

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;

Mais comment trouver la position de l'expression rationnelle?

J'ai entendu parler d'UDF mais je ne peux pas l'utiliser, j'utilise l'hébergement OVH.

14
Marek Andrzejak

Cela devrait utiliser la syntaxe LOCATE et SUBSTRING pour extraire les informations de la chaîne. La syntaxe de localisation de base dont vous auriez besoin est expliquée ici .

LOCATE (recherche str, str, [position])

search str = Une chaîne qui sera recherchée.

str = Une chaîne qui va être recherchée.

position (facultatif) = Position à partir de laquelle (dans le deuxième argument) la recherche commencera.

Alors que la fonction de sous-chaîne dont vous avez besoin est expliquée ici

SUBSTRING (str, pos, len)

str = Une chaîne.

pos = Position de départ.

len = Longueur en caractères.

La façon la plus simple de voir cela est de considérer la sous-chaîne comme la sous-chaîne suivante (str FROM pos FOR len)

La syntaxe que j'ai utilisée pour obtenir le deuxième mot est ci-dessous, j'ai profité des espaces qui sont constamment autour du deuxième mot que vous essayez d'extraire.

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

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

Malheureusement, la fonction d'expression régulière de MySQL renvoie true, false ou null selon que l'expression existe ou non.

L'astuce pour effectuer le comportement souhaité consiste à déterminer quelle sous-chaîne commence par le caractère qui vous intéresse, a la bonne longueur et est suivie d'un nombre. Une série de fonctions substring_index sont utilisées pour extraire la chaîne ...

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)
1
RMathis