Как вывести подстроку, соответствующую шаблону в PostgreSQL

Мне нужно найти шаблон, который даст мне подстроку, которая следует логике подстроки с правой стороны, после третьего _.

Чего я хочу добиться, так это получить все до 3-го _ .

Я пробовал этот SQL, но он не работал

select 
    SUBSTRING('22D_XYZ_xy_100_xyz_123', 1, position('_' in REVERSE('22D_XYZ_xy_100_xyz_123')) - 1) as result;

Он возвращает 22D, тогда как я ожидаю 22D_XYZ_xy

А что надо вернуть?

nbk 29.04.2023 09:20

Все до третьей подстроки.

Przemek 29.04.2023 09:28

Итак, вы ожидаете 22D_XYZ_xy? Пожалуйста, добавьте всю необходимую информацию

nbk 29.04.2023 09:34

Отвечает ли это на ваш вопрос? Извлечь текст до N-го символа в строке

nbk 29.04.2023 09:37

Добавил всю актуальную информацию.

Przemek 29.04.2023 09:55

Пожалуйста, посмотрите по ссылке, есть некоторые решения

nbk 29.04.2023 09:57
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
6
57
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы можете попробовать этот запрос

SELECT 
    REGEXP_SUBSTR('22D_XYZ_xy_100_xyz_123', '^[^_]+_[^_]+_[^_]+') as result;

Смотрите демо здесь

Ответ принят как подходящий

Фразу «подстрока, которая следует логике к подстроке с правой стороны после третьего _», трудно понять. Я предполагаю, что предполагаемое поведение состоит в том, чтобы извлечь подстроку, которая включает весь текст перед третьим _ справа, а не весь текст перед третьим _ слева. При поиске слева также возникает неоднозначность в отношении ожидаемого поведения, если символов _ меньше трех: следует ли возвращать всю строку или результатом должен быть NULL? К сожалению, входной пример 22D_XYZ_xy_100_xyz_123 и ожидаемый результат 22D_XYZ_xy согласуются со всеми этими случаями. Следующий запрос демонстрирует все три интерпретации:

SELECT
  string,
  regexp_substr(string, '^.*(?=(_[^_]*){3}$)') as from_right,
  regexp_substr(string, '^([^_]*_){0,2}[^_]*') as from_left,
  regexp_substr(string, '^([^_]*_){2}[^_]*(?=_)') as from_left_requires_3
FROM (
  VALUES ('22D_XYZ_xy_100_xyz_123'),
         ('1_2_3_4_5_6_7'),
         ('1_2_3_4_5_6'),
         ('1_2_3_4_5_'),
         ('_1_2_3_4_5'),
         ('1_2_3_4_5'),
         ('1_2_3_4'),
         ('1_2_3'),
         ('1_2_'),
         ('1_2'),
         ('1'),
         ('____'),
         ('___'),
         ('__'),
         ('_'),
         (''),
         (NULL)) t(string);

Выполнение запроса дает следующее:

нить from_right from_left from_left_requires_3 '22D_XYZ_xy_100_xyz_123' '22D_XYZ_xy' '22D_XYZ_xy' '22D_XYZ_xy' '1_2_3_4_5_6_7' '1_2_3_4' '1_2_3' '1_2_3' '1_2_3_4_5_6' '1_2_3' '1_2_3' '1_2_3' '1_2_3_4_5_' '1_2_3' '1_2_3' '1_2_3' '_1_2_3_4_5' '_1_2' '_1_2' '_1_2' '1_2_3_4_5' '1_2' '1_2_3' '1_2_3' '1_2_3_4' '1' '1_2_3' '1_2_3' '1_2_3' НУЛЕВОЙ '1_2_3' НУЛЕВОЙ '1_2_' НУЛЕВОЙ '1_2_' НУЛЕВОЙ '1_2' НУЛЕВОЙ '1_2' НУЛЕВОЙ '1' НУЛЕВОЙ '1' НУЛЕВОЙ «____» '_' '__' '__' '___' '' '__' '__' '__' НУЛЕВОЙ '__' НУЛЕВОЙ '_' НУЛЕВОЙ '_' НУЛЕВОЙ '' НУЛЕВОЙ '' НУЛЕВОЙ НУЛЕВОЙ НУЛЕВОЙ НУЛЕВОЙ НУЛЕВОЙ

Для поиска справа используется утверждение нулевой длины с положительным просмотром вперед, (?=(_[^_]*){3}$), чтобы проверить, что несопоставленная часть строки начинается с _ и содержит ровно три символа _. Если утверждение неверно, то возвращается NULL.

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

Поиск левой подстроки, предшествующей требуемому третьему _, аналогичен поиску левой подстроки, содержащей не более двух символов _, за исключением того, что спецификатором вхождения для группы является {2} вместо {0,2}, а утверждение нулевой длины с положительным просмотром вперед, (?=_), гарантирует, что _ — первый непревзойденный символ. Как и при поиске справа, если утверждение ложно, возвращается NULL.

Другие вопросы по теме