Oracle 中 REGEXP_SUBSTR 的正则表达式

Regular Expression for REGEXP_SUBSTR in Oracle

我要搜索以下文字:

#S7Z OK
#Wed Feb 18 07:16:26 GMT 2015
expiration=10.0
lastModified=1424192425832
length=466472
path=/name/_master_/563/5638ad54-8079-4399-ba2b-3257b6e6c7fd.pdf 
userType=

每个 = 前面的词是属性的名称。对于每个 属性 名称,我想获得 属性 值。这意味着我正在寻找一个与 regexp_substr 一起使用的正则表达式来获取每个已知 属性.

的值

像这样:

SELECT REGEXP_SUBSTR(
'#S7Z OK
#Wed Feb 18 07:16:26 GMT 2015
expiration=10.0
lastModified=1424192425832
length=466472
path=/name/_master_/563/5638ad54-8079-4399-ba2b-3257b6e6c7fd.pdf 
userType=',
'path=.+')
FROM dual

其中returns: 路径=/名称/master/563/5638ad54-8079-4399-ba2b-3257b6e6c7fd.pdf

但我只想要值,即“/name/master/563/5638ad54-8079-4399-ba2b-3257b6e6c7fd.pdf”。 它也应该适用于过期、lastModified 等,也就是说,我不只是想搜索 url,而是任何类型的值。

如何在一个正则表达式中实现这一点?

'。 +=' 作为第二个参数 '' 作为第三个参数

SELECT REGEXP_SUBSTR(
'#S7Z OK
#Wed Feb 18 07:16:26 GMT 2015
expiration=10.0
lastModified=1424192425832
length=466472
path=/name/_master_/563/5638ad54-8079-4399-ba2b-3257b6e6c7fd.pdf 
userType=',
'path=(.+)', 1, 1, null, 1)
FROM dual;

您可以通过以下方式一次性捕获所有 name=value 对。请注意,我在正则表达式中使用了显式量词 {1,10} 来防止灾难性回溯。 (这个特定的正则表达式实际上可能不受此约束,在这种情况下,您可以用 + 替换显式量词。但最好不要冒险!)

WITH s1 AS (
    SELECT '#S7Z OK
#Wed Feb 18 07:16:26 GMT 2015
expiration=10.0
lastModified=1424192425832
length=466472
path=/name/_master_/563/5638ad54-8079-4399-ba2b-3257b6e6c7fd.pdf 
userType=' AS str
      FROM dual
)
SELECT SUBSTR(name_value, 1, INSTR(name_value, '=') - 1) AS myname
     , SUBSTR(name_value, INSTR(name_value, '=') + 1, LENGTH(name_value)) AS myvalue
  FROM (
    SELECT REGEXP_SUBSTR(REGEXP_SUBSTR(s1.str,'(\S+=\S*\s*){1,10}'), '\S+', 1, LEVEL) AS name_value
      FROM s1
   CONNECT BY REGEXP_SUBSTR(REGEXP_SUBSTR(s1.str,'(\S+=\S*\s*){1,10}'), '\S+', 1, LEVEL) IS NOT NULL
);

输出如下:

MYNAME       | MYVALUE
-------------------------------------------------------------------------
expiration   | 10.0
lastModified | 1424192425832
length       | 466472
path         | /name/_master_/563/5638ad54-8079-4399-ba2b-3257b6e6c7fd.pdf
userType     | (null)

Please see SQL Fiddle here.

请注意,我本可以在外部查询中使用 REGEXP_SUBSTR(name_value, '^[^=]+') 等,但我认为此查询中有足够的正则表达式(这有点贵,我确信 SUBSTR() 加上 INSTR()更便宜!)。另外请注意,如果您使用的是 Oracle 11g 或更高版本,则 CONNECT BY 子句可以替换为以下内容:

CONNECT BY LEVEL <= REGEXP_COUNT(REGEXP_SUBSTR(s1.str,'(\S+=\S*\s*){1,10}'), '\S+')

See revised SQL Fiddle.