Skip to Main Content
  • Questions
  • need to extract numbers from a varchar upto a non-numeric character

Breadcrumb

Question and Answer

Connor McDonald

Thanks for the question, Philip.

Asked: September 19, 2017 - 7:48 pm UTC

Last updated: October 27, 2017 - 2:34 pm UTC

Version: 12.1.0.2.0

Viewed 10K+ times! This question is

You Asked

Hi,
I have a column called house number which is a varchar2, and it has all kinds of combinations of data entered (incorrect format) as shown below:

House_Number
-------------
416-A
416-A
1573A
131# A23
133 A-21
133 A22
13320A
133A-21
133A22
539# APT 3
563 # A5
339-REA
339REAR
23-REA
23REAR
231 # 303A

All i need to do is extract the house number before ascii characters or special characters or spaces.
So for the above column values the extracted output should be like below:
House_Number Extracted output should be like
------------ --------------------------------
416-A 416
416-A 416
1573A 1573
131# A23 131
133 A-21 133
133 A22 133
13320A 13320
133A-21 133
133A22 133
539# APT 3 539
563 # A5 563
339-REA 339
339REAR 339
23-REA 23
23REAR 23
231 # 303A 231
527# 2ND 527
5422NDFL 5422 (not sure if we can extract only 542, but at least the numbers before ascii characters or special characters or spaces)

I tried the regexp_substr...but i am not able to get the correct output for all the inputs.

Would appreciate if someone can help.

Thanks.
Philip.



and Connor said...

You read the guidelines right ?

GOOD_BAD

We *do* want to help you ... but you gotta help us

Rating

  (7 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Philip Ebenezer, September 20, 2017 - 1:32 pm UTC

Appreciate your response. I will make sure my future questions are better version.

Not The Most Elegant

SeanMacGC, September 20, 2017 - 4:04 pm UTC

But will get the job done:

SELECT SUBSTR('13320A',1, REGEXP_INSTR('13320A','[^[:digit:]]')-1) "REGEXPR_SUBSTR" FROM DUAL;
REGEX
-----
13320

SELECT SUBSTR('131# A23',1, REGEXP_INSTR('131# A23','[^[:digit:]]')-1) "REGEXPR_SUBSTR" FROM DUAL;
REG
---
131

Or equally:

SELECT SUBSTR('131# A23',1, REGEXP_INSTR('131# A23','[^0-9]')-1) "REGEXPR_SUBSTR" FROM DUAL;
&
SELECT SUBSTR('13320A',1, REGEXP_INSTR('13320A','[^0-9]')-1) "REGEXPR_SUBSTR" FROM DUAL;

@SeanMacGC from Dublin

Stew Ashton, September 20, 2017 - 5:10 pm UTC

regexp_substr(<input>, '^\d+')

'^' means anchor at the beginning.
\d is Perl shorthand for digits.
+ means 1 to as many a possible.
regexp_substr will just return the part that matches the pattern.

Best regards, Stew Ashton

Thank you Stew Ashton

SeanMacGC, September 21, 2017 - 7:18 am UTC

Concise and elegant.

Reason?

Racer I., September 21, 2017 - 11:30 am UTC

I would submit that alle parts of a housenumber may be relevant. Nothing says is has to be an integer.

regards,
Connor McDonald
September 22, 2017 - 12:35 am UTC

Agreed.

Non Elegant Solution

Chuck Jolley, September 22, 2017 - 3:10 pm UTC

The times I've had to do something similar it has never worked well enough to do it elegantly. Too many clinkers.
It's been: "Get to know the data intimately and then write a custom function."
Especially if the data has been entered by hand.

I think it should work

Harshit, October 27, 2017 - 12:15 pm UTC

1 ) SELECT regexp_substr ('131# A23', '[0-9]+', 1, 1) RESULT
FROM dual;
RESULT
--------------------------------
131


2 ) SELECT regexp_substr ('539# APT 3 ', '[0-9]+', 1, 1) result
FROM dual;

RESULT
--------------------------------
539

3) SELECT regexp_substr ('339REAR ', '[0-9]+', 1, 1) result
FROM dual;

RESULT
--------------------------------
339

Note : Do correct me if its wrong
Connor McDonald
October 27, 2017 - 2:34 pm UTC

maybe not :-)

SQL> SELECT regexp_substr ('XA131# A23', '[0-9]+', 1, 1) RESULT FROM dual;

RES
---
131


More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library