Jak korzystać z SUBSTRING przy użyciu REGEXP w MySQL

14

Mam następującą sytuację. Muszę podciągać wyrażenie regularne z opisu używając MySQL. Opis:

Lorem D9801 ipsum dolor sit amet

Gdzie D9801 to REGEXP. Każdy silny opis tekstowy ma inną treść, ale moje wyrażenie regularne powinno wyglądać następująco: REGEXP „D [[: digit:]] {4}”

REGEXP zawsze ma „D” na początku, a „xxxx” - 4 cyfry na końcu: Dxxxx

Wiem, że REGEXP zwraca tylko wartość prawda / fałsz, ale jak mogę wykonać zapytanie, aby zwrócić tylko wartość „D9801”?

Próbowałem czegoś takiego:

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

Wiem, że to źle, więc próbuję z tym:

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;

Ale jak znaleźć pozycję wyrażenia regularnego?

Słyszałem o UDF, ale nie mogę go używać, korzystam z hostingu OVH.

Marek Andrzejak
źródło
Jest to w zasadzie duplikat: stackoverflow.com/questions/4021507/…
Nathan Feger
Bez użycia funkcji UDF nie ma wbudowanej funkcji pobierania dopasowanego wzorca z funkcji REGEXP, a inne metody dopasowania polegają na znajomości pełnego pasującego łańcucha, dla którego nie działa w tej sytuacji
Ładunek

Odpowiedzi:

3

Musi to użyć składni LOCATEi, SUBSTRINGaby uzyskać informacje z ciągu. Podstawowa składnia lokalizacji, której potrzebujesz, została wyjaśniona tutaj .

LOCATE (szukaj str, str, [pozycja])

search str = Ciąg, który będzie wyszukiwany.

str = Ciąg, który będzie przeszukiwany.

position (opcjonalne) = Pozycja, z której (w ramach drugiego argumentu) rozpocznie się wyszukiwanie.

Chociaż funkcja podciągania, której potrzebujesz, jest wyjaśniona tutaj

SUBSTRING (str, pos, len)

str = ciąg.

pos = pozycja początkowa.

len = długość w znakach.

Najłatwiejszym sposobem przeglądania tego jest myślenie o podciągu jako o następującym SUBSTRINGU (str FROM pos FOR len)

Sytax, którego użyłem, aby uzyskać drugie słowo, jest poniżej. Wykorzystałem spacje, które są stale wokół drugiego słowa, które próbujesz wyodrębnić.

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

SUBSTRING
(
@String,
LOCATE(' ', @String),
LOCATE(' ', @String, (LOCATE(' ', @String) + 1)) - LOCATE(' ', @String)
)
James Rhoat
źródło
1

Niestety funkcja wyrażeń regularnych MySQL zwraca true, false lub null w zależności od tego, czy wyrażenie istnieje, czy nie.

Sztuczka w realizacji pożądanego zachowania polega na określeniu, który podciąg zaczyna się od znaku, na którym ci zależy, ma prawidłową długość, a po nim następuje liczba. Szereg funkcji substring_index służy do wyodrębnienia ciągu ...

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
źródło