Jak wyciągnąć wszystkie wyrazy o danym rozszerzeniu z jednego stringa

0

Witajcie

Mam np taki string: XXX.txt;JJJ.DLL;zzz.sql;ooo.txt;ccc.SQL;uuu.bmp;ggg.sql
potrzebowałbym jakimś substringiem lub wyrażeniem regularnym regexp_substr wyciągnąć wszystkie wyrazy, które kończą się na .sql (bez względu na upper/lower case).
finalnie potrzebuję uzyskać coś takiego:
zzz.sql;ccc.sql;ggg.sql
Oczywiście string może mieć dowolną ilość wystąpień, a ja potrzebuję wszystkie (oczywiście uwzględniając 4000 znaków wynikających z typu VARCHAR2).

Zrobiłem to funkcją ale nie jest to dla mnie eleganckie rozwiązanie dlatego pytam czy jakimś regexp da się uzyskać taki efekt jak bym chciał?

0

tak mozesz uzyc SELECT SUBSTRING('abcDEF123455xdgZ', 'Tu twoje wyrazenie reg');

0

No właśnie o to wyrażenie regularne pytam. Czy jesteś w stanie podać mi jakiś konkret?

0

Trzeba przeanalizować co tu zaszło :) Najpierw można dać '[0-9A-z]*.sql' ale nawias [] można zamienić na [^;] każdy znak z wyjątkiem ';' to tak jakbysmy podzielii sobie ten string na mniejsze części (w teorii). Następnie + czyli dopasowujemy sobie jedno lub więcej powtórzeń tego co chcemy przed .sql mieć. no a znak . zamienia nam znak specjalny (.) na kropkę bo inaczej sama . oznacza dowolny znak a nas interesuje konkretnie .sql. flaga 'gi' oznacza Global i Incasesensitive jakos tak to wyczytalem z dokumentacji teraz bo sam bym na to nigdy nie wpadł bo sie nie znam za bardzo na tym

SELECT 
  regexp_matches(
    'XXX.txt;JJJ.DLL;zzz.sql;ooo.txt;ccc.SQL;uuu.bmp;ggg.sql',
    E'([^;]+\.sql)',
    'gi'
  );

Albo możesz jeszcze użyć unnest

SELECT 
  unnest(
    regexp_matches(
      'XXX.txt;JJJ.DLL;zzz.sql;ooo.txt;ccc.SQL;uuu.bmp;ggg.sql',
      E'([^;]+\.sql)',
      'gi'
    )
  );
0

Zanim przeczytałem twoją odpowiedź zrobiłem to po swojemu:

select LISTAGG(plik,',') WITHIN GROUP (order by plik)
     from (SELECT REGEXP_SUBSTR(str, '[^'||';'||']+', 1, LEVEL) AS plik
             FROM (SELECT 'XXX.txt;JJJ.DLL;zzz.sql;ooo.txt;ccc.SQL;uuu.bmp;ggg.sql;' AS str FROM DUAL)
          CONNECT BY LEVEL <= LENGTH(REGEXP_REPLACE(str, '[^'||';'||']+')))
     group by substr(plik,length(plik)-3)
     having  upper(substr(plik,length(plik)-3))='.SQL';

Problem z tym rozwiązaniem jest taki, że LISTAGG nie działa na wszystkich wersjach oracle chyba od wersji 11 w górę działa :)

0

A ja po swojemu zrobiłem tak :

SELECT regexp_matches('XXX.txt;JJJ.DLL;zzz.sql;ooo.txt;ccc.SQL;uuu.bmp;ggg.sql', '[0-9A-z]*.sql', 'g');

ale sprawdzałem tylk ona postgresie

0

Jeszcze jedna prostsza wersja:

SELECT wm_concat(REGEXP_SUBSTR(pliki, '[^;]+sql',1, level,'i')) RESULT FROM DUAL connect by level <= REGEXP_COUNT(pliki, '[^;]+sql',1,'i');

1 użytkowników online, w tym zalogowanych: 0, gości: 1