Регулярное выражение для удаления элемента не соответствует конкретному префиксу - PullRequest
0 голосов
/ 28 июня 2018

Я делаю это в Импале или Улье. В основном, скажем, у меня есть такая строка

f-150:aa|f-150:cc|g-210:dd

Каждый элемент отделен трубой |. У каждого есть префикс f-150 или любой другой. Я хочу иметь возможность удалить префикс и сохранить только тот элемент, который соответствует конкретному префиксу. Например, если префикс f-150, я хочу, чтобы конечная строка после regex_replace была

aa|cc

dd удалено, поскольку g-210 - это другой префикс и не совпадает, поэтому весь элемент удаляется.

Есть идеи, как это сделать, используя строковое выражение в одном SQL?

Спасибо

ОБНОВЛЕНИЕ 1

Я пробовал это в Impala:

select regexp_extract('f-150:aa|f-150:cc|g-210:dd','(?:(?:|(\\|))f-150|keep|those):|(?:^|\\|)\\w-\\d{3}:\\w{2}',0);

Но получил этот вывод:

f-150:aa

В Hive я получил NULL.

Ответы [ 3 ]

0 голосов
/ 28 июня 2018

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

f-150:|\|[^:]+:[^|]+$|[^|]+:[^|]+\|

f-150:|\\|[^:]+:[^|]+$|[^|]+:[^|]+\\|

Объяснение

  • f-150: Совпадение буквально
  • | или
  • \|[^:]+:[^|]+$ Сопоставьте трубу, а не двоеточие один или несколько раз, а затем не трубу один или несколько раз и подтвердите конец строки
  • | или
  • [^|]+:[^|]+\| Сопоставить не трубу один или несколько раз, двоеточие, затем сопоставить не трубу один или несколько раз, а затем сопоставить трубу

Тест с несколькими строками и комбинациями

0 голосов
/ 29 июня 2018

Возможно, вам придется перебирать строку до конца, чтобы получить все соответствующие подстроки. Взгляд в будущее Синтаксис не поддерживается в большинстве sql, поэтому приведенное выше регулярное выражение может не подходить для синтаксиса SQL. Для вашей цели вы можете сделать что-то вроде создания таблицы для циклического прохождения, просто для имитации синтаксиса уровня Oracle и объединения с вашей таблицей, содержащей строку.

With loop_tab as (
Select 1 loop union all
Select 2 union all
select 3 union all
select 4 union all
select 5),
string_tab as(Select 'f-150:aa|ade|f-150:ce|akg|f-150:bb|'::varchar(40) as str)
Select regexp_substr(str,'(f\\-150\\:\\w+\\|)',1,loop)
from string_tab
join loop_tab on 1=1

Выход:

regexp_substr
f-150:aa|
f-150:ce|
f-150:bb|
0 голосов
/ 28 июня 2018

Регулярное выражение может выглядеть так:

(?:(?:|(\\|))f-150|keep|those):|(?:^|\\|)\\w-\\d{3}:\\w{2}

Я добавил несколько псевдо-ключевых слов для сохранения, но я уверен, что вы поняли:

  • Все элементы соответствия, которые должны быть отброшены, но соответствуют префиксу только тех, которые должны быть сохранены.
  • Чтобы сохранить разделитель без изменений, сопоставьте | в начале элемента в группе 1 и поместите его в замену с $1.

Демо

Согласно документации ваш запрос должен быть написан как Java regex ; аналогично, это должно работать так: пример кода в Java .

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