Як використовувати SUBSTRING за допомогою REGEXP в MySQL


14

У мене така ситуація. Мені доводиться підстроковувати регулярний вираз з опису за допомогою MySQL. Опис:

Lorem D9801 ipsum dolor sit amet

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

REGEXP завжди має "D" на початку та "xxxx" - 4 цифри в кінці: Dxxxx

Я знаю, що REGEXP повертає лише справжнє / хибне значення, але як я можу зробити запит, щоб повернути лише значення "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;

Але як знайти позицію regexp?

Я чув про UDF, але не можу ним користуватися, я використовую OVH хостинг.


Це в основному копія: stackoverflow.com/questions/4021507/…
Натан Фегер

Без використання UDF не існує вбудованої функціональності для отримання узгодженого шаблону з функції REGEXP, а інші методи узгодження покладаються на знання повної строки, для якої ви співпадаєте, для якої не працює в цій ситуації
Payload

Відповіді:


3

Для цього потрібно використовувати синтаксис LOCATEі SUBSTRINGдля отримання інформації з рядка. Основний синтаксис знайти вам потрібно буде пояснено тут .

LOCATE (пошук str, str, [позиція])

search str = Рядок, який буде шукати.

str = Рядок, який буде шукати.

позиція (необов'язково) = Позиція, з якої (у другому аргументі) розпочнеться пошук.

Хоча тут потрібна функція підрядки, яка пояснюється

ПІДТРИМКА (str, pos, len)

str = Рядок.

pos = Початкове положення.

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

Найпростішим способом перегляду цього є уявлення про підрядку як наступну ПІДТРИМКА (str від pos ДЛЯ 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)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.