Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Postgresql REGEXP_SPLIT_TO_TABLE-我想从完整路径获取不带扩展名的文件名_Regex_Postgresql - Fatal编程技术网

Postgresql REGEXP_SPLIT_TO_TABLE-我想从完整路径获取不带扩展名的文件名

Postgresql REGEXP_SPLIT_TO_TABLE-我想从完整路径获取不带扩展名的文件名,regex,postgresql,Regex,Postgresql,我在PostgreSQL表中有一系列文件路径,我希望获得不带扩展名的文件名。显示了一些示例数据,另请参见fiddle- 期望结果- file1 file2 file2 file8.tar my_prog 现在,我一直在努力掌握正则表达式,我是一个新手,我已经取得了一些进展。这是我目前掌握的代码- SELECT regexp_split_to_table(w.file_name, '^/.*/.*/......../.../') AS fn FROM with_filename w 到目前为止

我在PostgreSQL表中有一系列文件路径,我希望获得不带扩展名的文件名。显示了一些示例数据,另请参见fiddle-

期望结果-

file1
file2
file2
file8.tar
my_prog
现在,我一直在努力掌握正则表达式,我是一个新手,我已经取得了一些进展。这是我目前掌握的代码-

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
现在,我遇到了很多问题-

我知道我的正则表达式“^/*/././././././././././././././././././”是一团乱麻。基本上,我正在将文件路径硬编码到regexp中,如您所见。我没有拿起我的程序,因为正则表达式太长了。我不确定我对重复组的概念是否正确,也就是说,我从到处都是点开始,经过一些阅读,我得到了点星符号

这是实现这一目标的最佳方式吗?我知道我必须能够改变/。/…-可能使用这个“^/*/”吗

最后,我的主要问题是我不知道如何保留文件名和消除扩展名。可能存在没有扩展名的文件。我将非常感激,不仅仅是有一个答案,而且还有一个关于正则表达式中发生的事情的解释!如果需要更多数据,请告诉我

我会在这里使用REGEXP\u替换:

上面使用的正则表达式模式是一种替代模式,通过删除其中一种模式,其工作原理如下:

^.*/       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
请注意,这避免了使用捕获组的开销。

我将在此处使用REGEXP\u REPLACE:

上面使用的正则表达式模式是一种替代模式,通过删除其中一种模式,其工作原理如下:

^.*/       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
请注意,这样可以避免使用捕获组的开销。

您可以在此处使用REGEXP\u REPLACE,通过匹配[^/]after来匹配final/forced之后的所有内容,然后使用带有可选.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
您可以在此处使用REGEXP_REPLACE,通过匹配[^/]after来匹配final/exforced之后的所有内容,然后使用带有可选.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

太好了,谢谢。恐怕只有一次美中不足。我确实提到过,有些文件根本没有扩展名,而您的代码无法跨越这一障碍,请看,您的代码是第一个运行的!很抱歉,我知道当人们带着新的信息回来时会很沮丧!我给了你一个解决办法。我们可以尝试修剪路径的前导部分和尾随部分。修剪前后是我在传统SQL中所做的方式!如果你能给我展示另一种方法,我将非常感激——如果你有时间的话。我总是觉得这是一种很好的学习方式——用不同的方法做同样的事情!它确实帮助了我的sql!无论如何,我都会把你的答案标记为正确且有用!再次感谢您的投票!老实说,我上面给出的方法可能是最干净的方法。我曾考虑使用SPLIT_PART,但问题是,我们不知道路径中的元素数。@CarySwoveland可能不知道,但我肯定会将其包括在这里,因为REGEXP_REPLACE只能替换字符串的一部分。不包括它可能是将来继承这段代码的人的债务。那太感谢了。恐怕只有一次美中不足。我确实提到过,有些文件根本没有扩展名,而您的代码无法跨越这一障碍,请看,您的代码是第一个运行的!很抱歉,我知道当人们带着新的信息回来时会很沮丧!我给了你一个解决办法。我们可以尝试修剪路径的前导部分和尾随部分。修剪前后是我在传统SQL中所做的方式!如果你能给我展示另一种方法,我将非常感激——如果你有时间的话。我总是觉得这是一种很好的学习方式——用不同的方法做同样的事情!它确实帮助了我的sql!无论如何,我都会把你的答案标记为正确且有用!再次感谢您的投票!老实说,我上面给出的方法可能是最干净的方法。我曾考虑使用SPLIT_PART,但问题是,我们不知道路径中的元素数。@CarySwoveland可能不知道,但我肯定会将其包括在这里,因为REGEXP_REPLACE只能替换字符串的一部分。不包括它可能是将来继承此代码的人的债务。谢谢-这很有帮助-什么是“\1”位?@Vérace\1表示我们正在用第一个捕获组[^/]*的内容替换匹配项?,哪个部分捕获了文件名谢谢-这很有帮助-“\1”位是什么?@Vérace\1表示我们正在用第一个捕获组[^/]*?”的内容替换匹配项?,
哪个部分捕获的文件名可以与正则表达式匹配?!.*\/.+?=\。这使用了一个消极的前瞻和一个积极的前瞻,我知道Postgres支持这两种方法,但lookbehinds不支持!。在满足消极前瞻时,!.\/,因为。*是贪婪的,所以内部正则表达式指针移动到最后一个/。+然后匹配一个或多个字符,包括句点,直到被正向前瞻(=\)停止,它匹配行中的最后一个句点。我从下面的注释中看到,您希望这适用于没有扩展名的文件名。在这种情况下,将我在之前的评论中建议的正则表达式更改为?!.*\/.+?=\.\124;'。在上一个例子中,如果发生错误,我怀疑“?!.*\/.+?=\。”应该是?!.*/.+?=\.|'因为正则表达式包含一个引号。我不能肯定,因为我不知道Postgres,但很多语言在这种情况下都需要双引号。还有,除了regexp_split_to_表,你还有一个函数仅仅提取regex匹配的内容吗?这只是一个猜测,因为我不知道Postgres,但应该是?!.*\/.+?=\.|'用双引号括起来?@CarySwoveland,以防你想知道我对这个话题感兴趣!您可以匹配正则表达式?!.*\/.+?=\。这使用了一个消极的前瞻和一个积极的前瞻,我知道Postgres支持这两种方法,但lookbehinds不支持!。在满足消极前瞻时,!.\/,因为。*是贪婪的,所以内部正则表达式指针移动到最后一个/。+然后匹配一个或多个字符,包括句点,直到被正向前瞻(=\)停止,它匹配行中的最后一个句点。我从下面的注释中看到,您希望这适用于没有扩展名的文件名。在这种情况下,将我在之前的评论中建议的正则表达式更改为?!.*\/.+?=\.\124;'。在上一个例子中,如果发生错误,我怀疑“?!.*\/.+?=\。”应该是?!.*/.+?=\.|'因为正则表达式包含一个引号。我不能肯定,因为我不知道Postgres,但很多语言在这种情况下都需要双引号。还有,除了regexp_split_to_表,你还有一个函数仅仅提取regex匹配的内容吗?这只是一个猜测,因为我不知道Postgres,但应该是?!.*\/.+?=\.|'用双引号括起来?@CarySwoveland,以防你想知道我对这个话题感兴趣!