Come usare SUBSTRING usando REGEXP in MySQL


14

Ho la seguente situazione. Devo sottoformare l'espressione regolare dalla descrizione usando MySQL. Descrizione:

Lorem D9801 ipsum dolor sit amet

Dove D9801 è REGEXP. Ogni descrizione di testo forte ha contenuti diversi ma il mio regexp dovrebbe apparire come: REGEXP 'D [[: digit:]] {4}'

REGEXP ha sempre "D" all'inizio e "xxxx" - 4 cifre alla fine: Dxxxx

So che REGEXP restituisce solo il valore vero / falso, ma come posso fare una query per restituire solo il valore 'D9801'?

Ho provato qualcosa del genere:

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

So che è sbagliato, quindi provo con questo:

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;

Ma come trovare la posizione di regexp?

Ho sentito parlare di UDF ma non posso usarlo, utilizzo l'hosting OVH.


Questo è fondamentalmente un dup di: stackoverflow.com/questions/4021507/…
Nathan Feger

Senza utilizzare un UDF non esiste alcuna funzionalità integrata per recuperare il modello corrispondente dalla funzione REGEXP e gli altri metodi di corrispondenza si basano sulla conoscenza della stringa completa per la quale non si è corrispondenti in questa situazione
Payload

Risposte:


3

Ciò dovrebbe utilizzare la sintassi LOCATEe SUBSTRINGper estrarre le informazioni dalla stringa. La sintassi di localizzazione di base di cui hai bisogno è spiegata qui .

LOCATE (cerca str, str, [position])

search str = Una stringa che verrà cercata.

str = Una stringa che verrà cercata.

position (opzionale) = Posizione da dove (all'interno del secondo argomento) inizierà la ricerca.

Mentre la funzione di sottostringa di cui hai bisogno è spiegata qui

SUBSTRING (str, pos, len)

str = Una stringa.

pos = Posizione iniziale.

len = Lunghezza in caratteri.

Il modo più semplice di visualizzarlo è pensare alla sottostringa come al seguente SUBSTRING (str FROM pos FOR len)

La sintassi che ho usato per ottenere la seconda parola è sotto, ho approfittato degli spazi che sono costantemente attorno alla seconda parola che stai cercando di estrarre.

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

SUBSTRING
(
@String,
LOCATE(' ', @String),
LOCATE(' ', @String, (LOCATE(' ', @String) + 1)) - LOCATE(' ', @String)
)

1

Sfortunatamente, la funzione di espressione regolare di MySQL restituisce vero, falso o nullo a seconda che l'espressione esista o meno.

Il trucco nell'effettuare il comportamento desiderato è determinare quale sottostringa inizia con il personaggio a cui tieni, ha la lunghezza corretta ed è seguita da un numero. Una serie di funzioni substring_index viene utilizzata per estrarre la stringa ...

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)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.