简体   繁体   中英

Find a 2nd set of digit in a string(SQL/PL-SQL)

I have a string which may be of below types

string          expected result
15-th-rp         15
15/12-rp         12
15-12-th         12
4-5-6            5

Now i have to find the digit, 1) If a string contains only 1digit set then same will be displayed. 2) If there are multiple set of digits between character then i have to find the 2nd set of digit. Please help me.

  with a as (
   select '15-th-rp' as data from dual
   union all
   select  '15/12-rp' from dual
   union all
   select  '15-12-th' from dual
   union  all
   select '4-5-6' from dual
  )
  select regexp_substr(data,'[0-9]+',REGEXP_INSTR(data,'[/|-]')+1) from a;

I think this is what you're after:

with a as (select '15-th-rp' data from dual union all
           select '15/12-rp' data from dual union all
           select '15-12-th' data from dual union all
           select '4-5-6' data from dual)
select data,
       coalesce(regexp_substr(data,'[0-9]+',1,2),
                regexp_substr(data,'[0-9]+',1,1)) extracted_data
from   a;

DATA     EXTRACTED_DATA
-------- --------------
15-th-rp 15            
15/12-rp 12            
15-12-th 12            
4-5-6    5     

The good thing about using COALESCE is that it won't evaluate the second (and subsequent) arguments unless they're required.

You didn't answer the question about whether '_1_2' should return 1 or 2 , so I'm assuming you'd want 1 .

REGEXP_SUBSTR(data, '[0-9]+', REGEXP_INSTR(data, '[^0-9][0-9]')+1)


A somewhat hacky way to get 2 from _1_2 (whilst also coping with _1 yielding 1 ) could be...

REGEXP_SUBSTR(data || '_' || data, '[0-9]+', 1, 2)


SQL Fiddle : http://sqlfiddle.com/#!4/a54bb/7

Do it in 2 steps. First match the first and second occurences of the pattern and then show the first set only if there is no second set (ie it's null).

with
a(data) as (
  select '15-th-rp' from dual union all
  select '15/12-rp' from dual union all
  select '15-12-th' from dual union all
  select '4-5-6' from dual
),
b(data, first, second) as (
  select
   data
  ,regexp_substr(data, '[[:digit:]]+')
  ,regexp_substr(data, '[[:digit:]]+', 1, 2)
  from a
)
select data, nvl(second, first) as result from b;

Returns result:

DATA     RESULT
-------- ------
15-th-rp 15
15/12-rp 12
15-12-th 12
4-5-6    5

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM