【发布时间】:2017-10-04 23:26:30
【问题描述】:
我有一组包含最少 1 个和最多 3 个值的字符串,格式如下:
123;456;789
123;123;456
123;123;123
123;456;456
123;456;123
我正在尝试编写一个正则表达式,以便可以找到在同一字符串上重复的值,因此如果您有 123;456;789,它将返回 null,但如果您有 123;456;456,它将返回 456 和对于123;456;123 返回123
我设法写了这个表达式:
(.*?);?([0-9]+);?(.*?)\2
它的工作原理是在没有重复值时返回null,但它并不完全返回我需要的值,例如:对于字符串123;456;456,它返回123;456;456,对于字符串@ 987654335@它返回123;123
我需要的是只返回表达式的([0-9]+) 部分的值,据我所知,这通常是使用非捕获组来完成的。但要么我做错了,要么 Oracle SQL 不支持这一点,就好像我尝试使用 ?: 语法一样,结果不是我所期望的。
关于如何在 oracle sql 上解决此问题有什么建议吗?此表达式的目的是在查询中使用它。
SELECT REGEXP_SUBSTR(column, "expression") FROM DUAL;
编辑:
其实根据https://docs.oracle.com/cd/B12037_01/appdev.101/b10795/adfns_re.htm
Oracle 数据库实现了符合 POSIX 扩展正则表达式 (ERE) 规范的正则表达式支持。
根据https://www.regular-expressions.info/refcapture.html
POSIX ERE 不支持非捕获组
【问题讨论】:
-
在我看来,你不需要正则表达式。您需要修复您的数据模型,这样您就不会将数字列表存储在分隔字符串中。
-
我知道存储这样的值不是最优的,但它不是我的数据库,所以我不能只是“修复数据模型”
-
您没有告诉我们示例中最后一行的内容:
123是123;456;123中的重复“字符串”吗?另外,如果字符串看起来像123;123;456;456怎么办?您需要返回什么 - 在字符串中找到的第一个子字符串(实际上是令牌)? -
另外:双引号是字符串的一部分,还是您只是将它们作为字符串分隔符?在 Oracle 中,字符串定界符是单引号而不是双引号。
-
所以我认为这将是一个有趣的做法(使用纯正则表达式)来做我相信你想做的事情。请注意,这使用 PCRE 正则表达式,并且可能在 POSIX 中不起作用(很可能,我的意思是它不起作用),但是,它确实回答了您的问题
"(?:(\d+);(?(?=\1)(?<duplicate>\d+)|(\d+));(?(?=\1|\2|\3)(?<duplicate>\d+)|(\d+)))"。在此处查看它的使用情况:regex101.com/r/31WULs/1
标签: regex posix oracle-sqldeveloper regexp-substr posix-ere