您的正则表达式存在一些问题;它将匹配(例如)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,因为它需要在匹配结束时使用逗号。您可以通过将(.+?) 替换为[^ ]* 并将\, 替换为(,|$) 来解决这些问题。然后,您可以使用源自this question 的解决方案(尽管以我的首选形式,在CONNECT BY 中检查NOT NULL)来获得所有结果:
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
Demo on dbfiddle