我确实从这个答案开始: Oracle 11g get all matched occurrences by a regular expression
但它并没有让我足够远。我有一个字符串字段,如下所示:
A =&安培; TOKEN1&安培; token2&安培; token3,B =&安培; token2&安培; token3&安培; token5
它可以有任意数量的令牌和任意数量的键。所需的输出是一组如下所示的行:
钥匙|令牌
A | &安培; TOKEN1
A | &安培; token2
A | &安培; token3
B | &安培; token2
B | &安培; token3
B | &安培; token5
事实证明这很难做到。
我从这里开始:
SELECT token from
(SELECT REGEXP_SUBSTR(str, '[A-Z=&]+', 1, LEVEL) AS token
FROM (SELECT 'A=&token1&token2&token3,B=&token2&token3&token5' str from dual)
CONNECT BY LEVEL <= LENGTH(REGEXP_REPLACE(str, '[A-Z=&]+', ',')))
Where token is not null
但是这会产生:
A=&
&
&
B=&
&
&
这让我无处可去。我认为我需要做一个嵌套的聪明选择第一个让我的地方
A=&token1&token2&token3
B=&token2&token3&token5
随后的选择可能会做一个聪明的提取以获得最终结果。
难住了。我试图在不使用程序或函数代码的情况下尝试这样做 - 我希望这个集合能够与其他查询结合使用,所以如果可以使用嵌套选择来实现这一点,那将是很好的。
更新:
SET DEFINE OFF
SELECT SUBSTR(token,1,1) as Key, REGEXP_SUBSTR(token, '&\w+', 1, LEVEL) AS token2
FROM
(
-- 1 row per key/value pair
SELECT token from
(SELECT REGEXP_SUBSTR(str, '[^,]+', 1, LEVEL) AS token
FROM (SELECT 'A=&token1&token2&token3,B=&token2&token3&token5' str from dual)
CONNECT BY LEVEL <= LENGTH(REGEXP_REPLACE(str, '[^,]+', ',')))
Where token is not null
)
CONNECT BY LEVEL <= LENGTH(REGEXP_REPLACE(token, '&\w+'))
这让我
A | &安培; TOKEN1
A | &安培; token2
B | &安培; token3
B | &安培; token2
A | &安培; token2
B | &安培; token3
除了小问题(A应该有一个令牌3,令牌4和令牌5无处可见)之外,哪种格式很棒?
答案 0 :(得分:0)
好问题!谢谢你!
select distinct k, regexp_substr(v, '[^&]+', 1, level) t
from (
select substr(regexp_substr(val,'^[^=]+=&'),1,length(regexp_substr(val,'^[^=]+=&'))-2) k, substr(regexp_substr(val,'=&.*'),3) v
from (
select regexp_substr(str, '[^,]+', 1, level) val
from (select 'A=&token1&token2&token3,B=&token2&token3&token5' str from dual)
connect by level <= length(str) - length(replace(str,','))+1
)
) connect by level <= length(v) - length(replace(v,'&'))+1
这是一个答案,似乎有效......但我不喜欢将val
分成k
和v
的中间 - 必须有一个更好的方式(如果Key总是一个字符,那么它很容易)。并且不得不放一个DISTINCT
来摆脱重复......很可能在进一步玩你可以清理它(或其他人可能)
编辑基于保持领先优势而关键是一个字符:
select distinct k, regexp_substr(v, '&[^&]+', 1, level) t
from (
select substr(val,1,1) k
, substr(regexp_substr(val,'=&.*'),1) v
from (
select regexp_substr(str, '[^,]+', 1, level) val
from (select 'A=&token1&token2&token3,B=&token2&token3&token5' str from dual)
connect by level <= length(str) - length(replace(str,','))+1
)
) connect by level < length(v) - length(replace(v,'&'))+1