Oracle中REGEXP_SUBSTR的正则表达式

时间:2015-02-18 10:01:00

标签: sql regex oracle 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=

每个进行的单词=属性的名称。对于每个属性名称,我想获取属性值。这意味着我正在寻找一个与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

返回: path = / name / master /563/5638ad54-8079-4399-ba2b-3257b6e6c7fd.pdf

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

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

3 个答案:

答案 0 :(得分:2)

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;

答案 1 :(得分:0)

&#39 ;. + ='作为第二个论点 ''作为第三个论点

答案 2 :(得分:0)

以下是您可以同时捕获所有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.