Как использовать SUBSTRING используя REGEXP в MySQL

14

У меня следующая ситуация. Я должен подстроки регулярное выражение из описания, используя MySQL. Описание:

Lorem D9801 Ipsum Долор Сит Амет

Где D9801 - это REGEXP. Каждое сильное текстовое описание имеет различное содержание, но мое регулярное выражение должно выглядеть так: REGEXP 'D [[: digit:]] {4}'

У REGEXP всегда есть «D» в начале и «xxxx» - 4 цифры в конце: Dxxxx

Я знаю, что REGEXP возвращает только значение true / false, но как мне сделать запрос, чтобы вернуть только значение 'D9801'?

Я попробовал что-то вроде этого:

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

Я знаю, что это неправильно, поэтому я пытаюсь с этим:

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;

Но как найти положение регулярного выражения?

Я слышал о UDF, но не могу его использовать, я использую хостинг OVH.

Марек Анджеяк
источник
Это в основном дупл: stackoverflow.com/questions/4021507/…
Натан Фегер
Без использования UDF нет встроенной функциональности для извлечения сопоставленного шаблона из функции REGEXP, а другие методы сопоставления полагаются на знание полной строки, для которой вы подходите, которая не работает в этой ситуации
полезная нагрузка

Ответы:

3

Для этого потребуется использовать LOCATEи SUBSTRINGсинтаксис , чтобы получить информацию из строки. Базовый синтаксис поиска, который вам нужен, объясняется здесь .

LOCATE (поиск str, str, [position])

search str = Строка, которая будет искать.

str = Строка, которую нужно найти.

position (необязательно) = позиция, с которой (в пределах второго аргумента) начнется поиск.

В то время как функция подстроки вам нужна, здесь объясняется

ПОДПИСЬ (str, pos, len)

str = строка

pos = Начальная позиция.

len = длина в символах.

Более простой способ просмотра этого - думать о подстроке как о следующей ПОДПИСИ (str FROM pos FOR len)

Синтаксис, который я использовал для получения второго слова, приведен ниже, я воспользовался пробелами, которые постоянно находятся вокруг второго слова, которое вы пытаетесь извлечь.

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

SUBSTRING
(
@String,
LOCATE(' ', @String),
LOCATE(' ', @String, (LOCATE(' ', @String) + 1)) - LOCATE(' ', @String)
)
Джеймс Роат
источник
1

К сожалению, функция регулярного выражения MySQL возвращает true, false или null в зависимости от того, существует выражение или нет.

Хитрость в реализации желаемого поведения состоит в том, чтобы определить, какая подстрока начинается с символа, который вам небезразличен, имеет правильную длину и сопровождается числом. Ряд функций substring_index используется для извлечения строки ...

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
источник