Comment utiliser SUBSTRING à l'aide de REGEXP dans MySQL

14

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 sit amet

Où D9801 est REGEXP. Chaque description textuelle forte a un contenu différent, mais mon expression rationnelle devrait ressembler à ceci: REGEXP 'D [[: digit:]] {4}'

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

Je sais que le REGEXP ne renvoie que la valeur vraie / fausse, 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.

Marek Andrzejak
la source
Il s'agit essentiellement d'un dup de: stackoverflow.com/questions/4021507/…
Nathan Feger
Sans utiliser un UDF, il n'y a pas de fonctionnalité intégrée pour récupérer le modèle correspondant à partir de la fonction REGEXP et les autres méthodes de correspondance reposent sur la connaissance de la chaîne complète que vous correspondez pour laquelle ne fonctionne pas dans cette situation
Charge utile

Réponses:

3

Cela devrait utiliser la syntaxe LOCATEet SUBSTRINGpour 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)
)
James Rhoat
la source
1

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)
RMathis
la source