无法在oracle中使用regex substr获得第二次出现的模式

时间:2018-05-09 08:45:27

标签: sql oracle

SELECT
  REGEXP_SUBSTR('500 ,Oracle 1234,123Parkway123aa 123, 768Redwood Shores, CA,',
                '\d+,\d+[^,]+,',1,2) "REGEXPR_SUBSTR"
  FROM DUAL;

期望是第二次出现的输出为123, 768Redwood Shores, 但是,我怎么能够正确地获得第一个出现模式而不是第二个,我完全理解为什么?有人可以向我解释一下,谢谢。

1 个答案:

答案 0 :(得分:4)

[TL; DR] 正则表达式找不到重叠匹配。

第一场比赛:

SELECT REGEXP_SUBSTR(
         '500 ,Oracle 1234,123Parkway123aa 123, 768Redwood Shores, CA,',
         '\d+,\d+[^,]+,',
         1,
         1
       ) "REGEXPR_SUBSTR"
FROM   DUAL;

时:

1234,123Parkway123aa 123,

它会在第一场比赛之后寻找第二场比赛(不与第一场比赛重叠);所以会在子字符串中寻找第二个匹配:

' 768Redwood Shores, CA,'

并且没有找到任何东西。

即使正则表达式确实支持重叠匹配(它们没有),也不会找到任何内容,因为在您的模式不匹配的逗号后面有空格。

这将允许重叠匹配(但更复杂并且不是单个函数):

SQL Fiddle

查询1

WITH data ( value ) AS (
  SELECT '500 ,Oracle 1234,123Parkway123aa 123, 768Redwood Shores, CA,'
  FROM   DUAL
),
pos ( value, match, pos, lvl ) AS (
  SELECT value,
         REGEXP_SUBSTR( value, '\d+,\s*\d+[^,]+?(\d*),', 1, 1 ),
         REGEXP_INSTR( value, '\d+,\s*\d+[^,]+?(\d*),', 1, 1, 0, NULL, 1 ),
         1
  FROM   data
UNION ALL
  SELECT value,
         REGEXP_SUBSTR( value, '\d+,\s*\d+[^,]+?(\d*),', pos, 1 ),
         REGEXP_INSTR( value, '\d+,\s*\d+[^,]+?(\d*),', pos, 1, 0, NULL, 1 ),
         lvl + 1
  FROM   pos
  WHERE  pos > 0
)
SELECT match
FROM   pos
WHERE  pos > 0
AND    lvl = 2

<强> Results

|                   MATCH |
|-------------------------|
| 123, 768Redwood Shores, |