Regex: получить предпоследнюю часть "пути" - PullRequest
1 голос
/ 10 октября 2019

У меня есть что-то вроде этого:

>AAA>BBB>CCC>DDD

С

([^>]*$)

Я получаю последнюю часть DDD. Как я могу получить часть до этого, CCC?

Спасибо!

Ответы [ 3 ]

2 голосов
/ 11 октября 2019

Вы можете использовать

REGEXP_SUBSTR('>AAA>BBB>CCC>DDD', '([^>]+)>[^>]+$', 1, 1, NULL, 1)

Регулярное выражение ([^>]+)>[^>]+$ будет сопоставлять и фиксировать в Группе 1 любые 1+ символов, отличных от >, затем будет совпадать с >, а затем с любыми 1+ символами, другимичем > до конца строки.

Последний аргумент 1 указывает REGEXP_SUBSTR вернуть только захваченную подстроку.

См. онлайн-демонстрация .

Другой подход - заменить всю строку, но оставить захваченную часть по вашему выбору:

REGEXP_REPLACE( '>AAA>BBB>CCC>DDD', '.*>([^>]+)>[^>]+$', '\1')

Посмотреть другую онлайн-демонстрацию .

Здесь .*> будет соответствовать всей строке до >, затем ([^>]+) будет захватывать любые 1+ символов, отличных от >, а затем >[^>]+$ будет совпадать и потреблять > и 1+ символов кроме > в конце строки.

1 голос
/ 11 октября 2019

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

with
  test_data (pth) as (
    select '>AAA>BBB>CCC>DDD' from dual union all
    select null               from dual union all
    select '>EEE>GGG'         from dual union all
    select '>JJJJJ'           from dual
  )
select pth, 
       regexp_substr(pth, '[^>]*', 1, nullif(2*regexp_count(pth, '>')-2, 0)) as stl
from   test_data
;

PTH              STL             
---------------- ----------------
>AAA>BBB>CCC>DDD CCC             

>EEE>GGG         EEE             
>JJJJJ      
1 голос
/ 11 октября 2019

Для этого вам не нужны регулярные выражения - достаточно стандартных строковых функций, и они будут намного быстрее.

В последнем примере обратите внимание на то, что нет ни второго, ни предпоследнегочасть;поэтому вывод равен NULL. Это действительно правильный ответ в этом случае.

with
  test_data (pth) as (
    select '>AAA>BBB>CCC>DDD' from dual union all
    select null               from dual union all
    select '>EEE>GGG'         from dual union all
    select '>JJJJJ'           from dual
  )
select pth,
       substr(pth, instr(pth, '>', -1, 2) + 1, 
              instr(pth, '>', -1, 1) - instr(pth, '>', -1, 2) - 1) as stl
from   test_data
;

PTH               STL             
----------------  ----------------
>AAA>BBB>CCC>DDD  CCC             

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