Postgresql REGEXP_SPLIT_TO_TABLE - Я хочу получить имя файла без расширения из полного пути - PullRequest
1 голос
/ 05 мая 2020

У меня есть ряд путей к файлам в таблице PostgreSQL, и я использую sh, чтобы получить имя файла без расширения. Показаны некоторые образцы данных (см. Также скрипт здесь ) -

VALUES
(1, '/users/mcm1/ualaoip2/vmm/file1.pdf'),
(2, '/users/mcm1/ualaoip2/vmm/file2.py'),
(3, '/users/mcm1/ualaoip2/vmm/file3.pdf'),
(8, '/users/mcm1/ualaoip2/vmm/file8.tar.gz'),
(9, '/users/mcm1/my_prog.cpp');

Желаемый результат -

file1
file2
file2
file8.tar
my_prog

Теперь я пытался gr asp регулярные выражения (я новичок ie), и я добился некоторого прогресса. Это код, который у меня есть до сих пор -

SELECT regexp_split_to_table(w.file_name, '^/.*/.*/......../.../') AS fn
FROM with_filename w

Результат на данный момент - есть пустая строка до и после каждой второй строки - не понимаю, почему!

fn

file1.pdf

file2.py

file3.pdf

file8.tar.gz

/users/mcm1/my_prog.cpp

Теперь, У меня было несколько проблем -

Я знаю, что мое регулярное выражение - '^/.*/.*/......../.../' - полный беспорядок. По сути, я жестко кодирую путь к файлу в регулярном выражении, как вы можете видеть. Я не набираю my_prog, потому что регулярное выражение слишком длинное. Я не уверен, что моя концепция повторяющихся групп верна - например, .* (я начал с точек везде и после некоторого чтения получил обозначение точка-звезда).

Это оптимальный способ выполнения этого? Я знаю, что должен иметь возможность изменять количество вхождений /../.. - возможно, используя это '^(/.*/)'?

Наконец, моя главная проблема в том, что я не знаю, как сохранить имя файла и устранить расширение. Могут быть файлы, у которых нет расширения. Буду признателен не только за ответ, но и за объяснение того, что происходит в регулярном выражении! Если требуются дополнительные данные, сообщите мне!

Ответы [ 2 ]

2 голосов
/ 05 мая 2020

Здесь вы можете использовать REGEXP_REPLACE, сопоставляя все после последнего / (принудительно путем сопоставления [^/] после, а затем использования ленивого сопоставления с необязательным расширением .xxx для сопоставления имени файла:

SELECT
    file_name,
    REGEXP_REPLACE(file_name, '^.*/([^/]*?)(\.[^/.]+)?$', '\1') AS filename
FROM with_filename;

Вывод:

file_name                               filename
/users/mcm1/ualaoip2/vmm/file1.pdf      file1
/users/mcm1/ualaoip2/vmm/file2.py       file2
/users/mcm1/ualaoip2/vmm/file3.pdf      file3
/users/mcm1/ualaoip2/vmm/file4.c        file4
/users/mcm1/ualaoip2/vmm/file5.java     file5
/users/mcm1/ualaoip2/vmm/file6.class    file6
/users/mcm1/ualaoip2/vmm/file7          file7
/users/mcm1/ualaoip2/vmm/file8.tar.gz   file8.tar
/users/mcm1/my_prog.cpp                 my_prog

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

2 голосов
/ 05 мая 2020

Я бы использовал REGEXP_REPLACE здесь:

SELECT
    id,
    path,
    REGEXP_REPLACE(path, '^.*/|\.[^.]+$', '') AS filename
FROM yourTable;

screen capture of demo below

Демо

Используемый выше шаблон регулярного выражения представляет собой чередование и работает следующим образом, удаляя либо:

^.*/       from the start of the path up, and including, the last / path separator
OR
|\.[^.]+$  the file extension at the end of the path, should it exist

Обратите внимание, что эти ответы позволяют избежать накладных расходов на использование группы захвата.

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