我有一个示例源代码字符串,如下所示,它采用管道分隔格式,因为值 obr 可以在任何地方。我需要从第一次出现的 obr 中获取管道的第二个值。因此对于下面的源字符串,预期的是,
源字符串:
select 'asd|dfg|obr|1|value1|end' text from dual
union all
select 'a|brx|123|obr|2|value2|end' from dual
union all
select 'hfv|obr|3|value3|345|pre|end' from dual
预期产出:
value1
value2
value3
我在oracle sql中尝试过以下regexp,但它运行不正常。
with t as (
select 'asd|dfg|obr|1|value1|end' text from dual
union all
select 'a|brx|123|obr|2|value2|end' from dual
union all
select 'hfv|obr|3|value3|345|pre|end' from dual
)
select text,to_char(regexp_replace(text,'*obr\|([^|]*\|)([^|]*).*$', '\2')) output from t;
当字符串以OBR开头时它工作正常,但是当OBR像上面的样本一样处于中间时它不能正常工作。
任何帮助都将不胜感激。
答案 0 :(得分:3)
不确定Oracle如何处理正则表达式,但从星号开始通常意味着您要查找零个或多个空字符。
您是否尝试过'^.*obr\|([^|]*\|)([^|]*).*$'
?
答案 1 :(得分:0)
这会处理null元素并包含在NVL()调用中,如果找不到'obr'或者在记录末尾发生太远而提供值,那么值2就不可能了:
SQL> with t(id, text) as (
select 1, 'asd|dfg|obr|1|value1|end' from dual
union
select 2, 'a|brx|123|obr|2|value2|end' from dual
union
select 3, 'hfv|obr|3|value3|345|pre|end' from dual
union
select 4, 'hfv|obr||value4|345|pre|end' from dual
union
select 5, 'a|brx|123|obriem|2|value5|end' from dual
union
select 6, 'a|brx|123|obriem|2|value6|obr' from dual
)
select
id,
nvl(regexp_substr(text, '\|obr\|[^|]*\|([^|]*)(\||$)', 1, 1, null, 1), 'value not found') value
from t;
ID VALUE
---------- -----------------------------
1 value1
2 value2
3 value3
4 value4
5 value not found
6 value not found
6 rows selected.
SQL>
正则表达式基本上可以理解为“查找管道模式,然后是'obr',后跟管道,后跟零个或多个不是管道的字符,后跟管道,后跟零或更多不是管道的字符(在捕获的组中记住),后跟管道或行的末尾“。然后regexp_substr()调用返回第一个捕获的组,它是来自'obr'的管道2字段之间的字符集。