MySQL'de REGEXP kullanarak SUBSTRING nasıl kullanılır


14

Bende şu durum var. MySQL kullanarak açıklama normal ifade subring gerekir. Açıklama:

Lorem D9801 ipsum dolor sit amet

Burada D9801, REGEXP'dir. Her güçlü metin açıklamasının içeriği farklıdır, ancak normal ifadem şöyle görünmelidir: REGEXP 'D [[: digit:]] {4}'

REGEXP'in başında daima "D" ve sonunda "xxxx" vardır - 4 rakam: Dxxxx

REGEXP yalnızca doğru / yanlış değer döndürür biliyorum, ama nasıl sadece 'D9801' değeri döndürmek için sorgu yapabilirim?

Ben böyle bir şey denedim:

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

Bunun yanlış olduğunu biliyorum, bu yüzden şunu deniyorum:

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;

Ama normal ifade konumu nasıl bulunur?

UDF'yi duydum ama kullanamıyorum, OVH hosting kullanıyorum.



Bir UDF kullanmadan, eşleşen deseni REGEXP işlevinden almak için yerleşik bir işlevsellik yoktur ve diğer eşleştirme yöntemleri, bu durumda çalışmayan tam dizeyi bilmeye dayanır
Payload

Yanıtlar:


3

Bunun , bilgileri dizeden çıkarmak için LOCATEve SUBSTRINGsözdizimini kullanması gerekir . İhtiyacınız olan temel yer belirleme sözdizimi burada açıklanmaktadır .

LOCATE (arama str, str, [konum])

search str = Aranacak bir dize.

str = Aranacak bir dize.

position (isteğe bağlı) = Aramanın başlayacağı konum (ikinci bağımsız değişken içinde).

İhtiyacınız olan alt dize işlevi burada açıklanırken

SUBSTRING (str, pos, len)

str = Bir dize.

pos = Başlangıç ​​konumu.

len = Karakter cinsinden uzunluk.

Bunu izlemenin daha kolay yolu, alt dizeyi aşağıdaki SUBSTRING olarak düşünmektir (str FROM pos FOR len)

İkinci kelimeyi elde etmek için kullandığım sytax aşağıda, ayıklamaya çalıştığınız ikinci kelimenin etrafındaki boşluklardan yararlandım.

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

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

1

Maalesef, MySQL'in normal ifade işlevi, ifadenin var olup olmamasına bağlı olarak true, false veya null değerini döndürür.

İstenen davranışı gerçekleştirmenin hilesi, hangi alt dizenin önem verdiğiniz karakterle başladığını, doğru uzunluğa sahip olduğunu ve ardından bir sayı geldiğini belirlemektir. Dizeyi ayıklamak için bir dizi subring_index işlevi kullanılır ...

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)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.