2

我有一个如下所示的示例源字符串,它采用管道分隔格式,因为值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 中尝试了以下正则表达式,但它不能正常工作。

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 像上面的示例一样位于中间时它不能正常工作。

任何帮助,将不胜感激。

4

2 回答 2

3

不确定 Oracle 如何处理正则表达式,但以星号开头通常意味着您正在寻找零个或多个空字符。

你试过'^.*obr\|([^|]*\|)([^|]*).*$'吗?

于 2015-11-18T17:34:43.363 回答
0

这处理空元素,并包装在 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 字段之间的字符集。

于 2015-11-18T19:19:55.460 回答