oracle 如何使用正则表达式提取第五次或第n次出现?

yzuktlbb  于 2023-05-16  发布在  Oracle
关注(0)|答案(3)|浏览(140)

我有一张这样的table

Jack|Sparrow|17-09-16|DY7009|Address at some where|details 

Jack|Sparrow|17-09-16|DY7009|

我想提取第五次或第n次出现的(使用|以确定它)。如果该行的出现次数少于5次,我想返回该行的最大出现次数。
下面是我的脚本:

with a as (
  select 'Jack|Sparrow|17-09-16|DY7009|Address at some where|details ' from dual test
  union all select 'Jack|Sparrow|17-09-16|DY7009|' from dual test
)
select substr(test,1,(REGEXP_instr(test,'[^|]+',1,5))) from a;

以下是我的结果:

Jack|Sparrow|17-09-16|DY7009|A
null

我的预期结果:

Jack|Sparrow|17-09-16|DY7009|Address at some where|
Jack|Sparrow|17-09-16|DY7009|

有什么办法可以让我这么做吗?多谢了。

d6kp6zgx

d6kp6zgx1#

您可以将整个列内容(包括最后的管道)作为一个组进行匹配,并使用匹配量词{m,n}捕获不超过5个组。然后使用regexp_substr提取匹配:

with a(test) as (
  select 'Jack|Sparrow|17-09-16|DY7009|Address at some where|details ' from dual
  union all select 'Jack|Sparrow|17-09-16|DY7009|' from dual
  union all select 'Jack|Sparrow|17-09-16' from dual
)
select
  test,
  REGEXP_substr(test,'([^|]+\|?){1,5}') as res
from a;
测试RES
杰克·|斯派洛|17-09-16| DY 7009|地址在一些地方|详情杰克·|斯派洛|17-09-16| DY 7009|地址在某个地方|
杰克·|斯派洛|17-09-16| DY 7009|杰克·|斯派洛|17-09-16| DY 7009|
杰克·|斯派洛|17-09-16杰克·|斯派洛|17-09-16

fiddle

9q78igpj

9q78igpj2#

尝试使用这样的查询,它应该可以解决您的问题:

with a as (
    select 'Jack|Sparrow|17-09-16|DY7009|Address at some where|details ' test from dual
    union all select 'Jack|Sparrow|17-09-16|DY7009|' test from dual
)
select 
  substr(
    test,
    1,
    decode(
      REGEXP_instr(test,'[^|]+', 1, 5, 1),
      0,
      REGEXP_instr(test,'[^|]+', 1, REGEXP_COUNT(test, '[^|]+'), 1),
      REGEXP_instr(test,'[^|]+', 1, 5, 1)
    )
  )
from a;

你可以使用查询here

igetnqfo

igetnqfo3#

或者,在没有正则表达式的情况下,使用标准的substr + instr组合(在大型数据集上可能性能更好)。
样本数据(从astentx借用;谢谢!):

SQL> with a (test) as (
  2    select 'Jack|Sparrow|17-09-16|DY7009|Address at some where|details ' from dual
  3    union all select 'Jack|Sparrow|17-09-16|DY7009|' from dual
  4    union all select 'Jack|Sparrow|17-09-16' from dual
  5  )

查询:

6  select test,
  7    substr(test, 1, case when instr(test, '|', 1, 5) = 0 then length(test)
  8                         else instr(test, '|', 1, 5) - 1
  9                    end
 10          ) as result
 11  from a;

TEST                                                        RESULT
----------------------------------------------------------- -----------------------------------------------------------
Jack|Sparrow|17-09-16|DY7009|Address at some where|details  Jack|Sparrow|17-09-16|DY7009|Address at some where
Jack|Sparrow|17-09-16|DY7009|                               Jack|Sparrow|17-09-16|DY7009|
Jack|Sparrow|17-09-16                                       Jack|Sparrow|17-09-16

SQL>

相关问题