Skip to Main Content

SQL & PL/SQL

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Interested in getting your voice heard by members of the Developer Marketing team at Oracle? Check out this post for AppDev or this post for AI focus group information.

regexp_substr

465486Oct 26 2007 — edited Oct 29 2007
Hello Gurus

I'm trying to extract 10999 from the string bellow with regexp, but

select regexp_substr('Fast10999/2/3/4','[0-9]+/') from dual

returns "10999/". How can I say something like return me the string of digits BEFORE the first slash?

Thank you all very much,

Comments

Sentinel
I don't have 10g but I think this will do it:
select regexp_substr('Fast10999/2/3/4','([0-9]+)/')
from dual;
214628
select replace(regexp_substr('Fast10999/2/3/4','[0-9]+/'),'/','') from dual
465486
Hello

And thank you for your reply but it doesn't work, still returns 10999/. I would like to end up with 10999.

Thank you,
465486
Hello

And thank you for your reply but I would like to solve this with regexp exclusively.

Thank you,
Sentinel
Ok grabbed XE

Just dropping the slash from your pattern does the trick:
select regexp_substr('Fast10999/2/3/4','[0-9]+') from dual;
and adding some of the optional parameters will get the other numbers:
select regexp_substr('Fast10999/2/3/4','[0-9]+',1,2) from dual;
select regexp_substr('Fast10999/2/3/4','[0-9]+',1,3) from dual;
select regexp_substr('Fast10999/2/3/4','[0-9]+',1,4) from dual;
465486
Yes,

But then

select regexp_substr('Fa234st10999/2/3/4','[0-9]+')
from dual;

would return 234 and I want the number before the first slash...

Thank you,
Aketi Jyuuzou

On 10gR2,
we can use ".*?".

SQL> col after for a20
SQL> with t as (
SQL> select 'Fa234st10999/2/3/4' s from dual union all
SQL> select 'Fa234st/2/3/4' from dual union all
SQL> select '23499/2/3/4' from dual union all
SQL> select 'abcdefg' from dual union all
SQL> select '1234567' from dual)
SQL> select s as before,
SQL> RegExp_Replace(s,'^.*?([0-9]+)/.*$','\1') as after
SQL> from t;
BEFORE              AFTER
------------------  -------
Fa234st10999/2/3/4  10999
Fa234st/2/3/4       2
23499/2/3/4         23499
abcdefg             abcdefg
1234567             1234567

Oracle11g have not supported "lookahead assertion" yet.
If Oracle support "lookahead assertion",
we can use "[0-9]+(?=/)"

MaximDemenko
SQL> set null '<null>'
SQL> with t as (
  2  select 'Fa234st10999/2/3/4' s from dual union all
  3  select 'Fa234st/2/3/4' from dual union all
  4  select '23499/2/3/4' from dual
  5  )
  6  select regexp_replace(s,'^(.*[^0-9/])*([0-9]*)/.*$','\2') r
  7  from t
  8  /

R
-----------------------------------------------------------------------------------------------------------------------------
10999
<null>
23499
Best regards

Maxim
572471
deleted

Message was edited by:
Volder
dmcghan
Hello all,

Is this cheating? ;)

SELECT regexp_substr(regexp_substr('Fa123st10999/2/3/4', '[[:digit:]]+/'),'[[:digit:]]+')
FROM dual

Dan
572471
Is this cheating? ;)
it is not cheating - it is double use of regular expression functions.

To use regexp only once - the OP can run depending on his/her needs one of the following:
SQL> with t as (
  2      select 'Fa234st10999/2/3/4' s from dual union all
  3      select 'Fa234st/2/3/4' from dual union all
  4      select '23499/2/3/4' from dual
  5      )
  6      select s,
  7             regexp_replace(s, '([[:digit:]]+)/.*|.', '\1') s1,
  8             regexp_replace(s, '([[:digit:]]*)/.*|.', '\1') s2
  9        from t
 10  /

S                  S1          S2
------------------ ----------- ----------
Fa234st10999/2/3/4 10999       10999
Fa234st/2/3/4      2           
23499/2/3/4        23499       23499

SQL> 
465486
Hello all,

Thank you for all your replies. The one that best suites my needs is:

select RegExp_Replace('Fa234st10999/2/3/4','^.*?([0-9]+)/.*$','\1') from dual

which says (for other people just getting into re):

Find the string

which starts from the begging of the string ^ followed by any character . zero or more times * zero or one times ? followed by a group () of digits [0-9] one or more times + followed by a / and followed by a character . zero or more times * till the end of the row $.
Take this string and replace it with the first group found \1.

I also chose this response cause it was shorter than others...

Thank you all again,
ebrian

Not to take away from Aketi's solution, I was kinda fond of Volder's solution myself.

I also chose this response cause it was shorter than others...

If it's simply a short regex that you are after, then working with Volder's solution, you could rewrite it as:

with t as (
      select 'Fa234st10999/2/3/4' s from dual union all
      select 'Fa234st/2/3/4' from dual union all
      select '23499/2/3/4' from dual
      )
      select s,
             regexp_replace(s, '(\d+)/.*|.', '\1') s1
        from t
/ 
1 - 13
Locked Post
New comments cannot be posted to this locked post.

Post Details

Locked on Nov 26 2007
Added on Oct 26 2007
13 comments
16,038 views