сохранить строку на основе подстроки - PullRequest
1 голос
/ 29 марта 2020

Мне нужно держать в строке те слова, которые включают в себя часть подстроки. Пример:

select regexp_substr('libstdc++-devel-4.8.5-39.0.3.el7.x86_64, python-kitchen-1.1.1-5.el7.noarch, nfs-utils-1.3.0-0.65.0.1.el7.x86_64, git-1.8.3.1-20.el7.x86_64', 
       '(.+?)(devel|git|nfs).+?\,') st from dual;

Этот запрос возвращает libstdc ++ - devel-4.8.5-39.0.3.el7.x86_64 , но мне также нужно git -1.8.3.1 -20.el7.x86_64 и nfs-utils-1.3.0-0.65.0.1.el7.x86_64 на основе шаблона. Обратите внимание, что у меня есть десятки слов в каждой строке (не только эти 4), поэтому мне нужно скорректировать шаблон, чтобы расширить результат (например, добавив grub, perl, et c). Спасибо.

1 Ответ

2 голосов
/ 29 марта 2020

У вас есть пара проблем с вашим регулярным выражением; он будет соответствовать (например) python-kitchen-1.1.1-5.el7.noarch, nfs-utils-1.3.0-0.65.0.1.el7.x86_64,, потому что он разрешает пробел и запятые перед совпадением с одним из devel, git или nfs(.+?)). Кроме того, он не будет совпадать с git-1.8.3.1-20.el7.x86_64, потому что в конце матча требуется запятая. Вы можете исправить эти проблемы, заменив (.+?) на [^ ]* и \, на (,|$). Затем вы можете использовать решение, полученное из этого вопроса (хотя в моей предпочтительной форме, проверяя NOT NULL в CONNECT BY), чтобы получить все ваши результаты:

SELECT REGEXP_SUBSTR(str, '[^ ]*(devel|git|nfs).+?(,|$)', 1, level) AS lib
FROM (
  SELECT 'libstdc++-devel-4.8.5-39.0.3.el7.x86_64, python-kitchen-1.1.1-5.el7.noarch, nfs-utils-1.3.0-0.65.0.1.el7.x86_64, git-1.8.3.1-20.el7.x86_64' as str
  FROM dual
)
CONNECT BY REGEXP_SUBSTR(str, '[^ ]*(devel|git|nfs).+?(,|$)', 1, level) IS NOT NULL

Вывод :

LIB
libstdc++-devel-4.8.5-39.0.3.el7.x86_64,
nfs-utils-1.3.0-0.65.0.1.el7.x86_64,
git-1.8.3.1-20.el7.x86_64

Обратите внимание, это оставляет запятые в конце некоторых имен, если вы хотите избавиться от них, просто используйте RTRIM:

SELECT RTRIM(REGEXP_SUBSTR(str, '[^ ]*(devel|git|nfs).+?(,|$)', 1, level), ',') AS lib
FROM (
  SELECT 'libstdc++-devel-4.8.5-39.0.3.el7.x86_64, python-kitchen-1.1.1-5.el7.noarch, nfs-utils-1.3.0-0.65.0.1.el7.x86_64, git-1.8.3.1-20.el7.x86_64' as str
  FROM dual
)
CONNECT BY REGEXP_SUBSTR(str, '[^ ]*(devel|git|nfs).+?(,|$)', 1, level) IS NOT NULL

Вывод:

LIB
libstdc++-devel-4.8.5-39.0.3.el7.x86_64
nfs-utils-1.3.0-0.65.0.1.el7.x86_64
git-1.8.3.1-20.el7.x86_64

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

WITH CTE AS (
  SELECT level AS l, REGEXP_SUBSTR(str, '[^ ]*(devel|git|nfs).+?(,|$)', 1, level) AS lib
  FROM (
    SELECT 'libstdc++-devel-4.8.5-39.0.3.el7.x86_64, python-kitchen-1.1.1-5.el7.noarch, nfs-utils-1.3.0-0.65.0.1.el7.x86_64, git-1.8.3.1-20.el7.x86_64' as str
    FROM dual
  )
  CONNECT BY REGEXP_SUBSTR(str, '[^ ]*(devel|git|nfs).+?(,|$)', 1, level) IS NOT NULL
)
SELECT LISTAGG(lib) WITHIN GROUP (ORDER BY l) AS lib
FROM CTE

Вывод:

LIB
libstdc++-devel-4.8.5-39.0.3.el7.x86_64,nfs-utils-1.3.0-0.65.0.1.el7.x86_64,git-1.8.3.1-20.el7.x86_64

Демонстрация на dbfiddle

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