Oracle Look behind Positive - sql

There is no example of look behind expression in Oracle Doc, so i tried using Java syntax,
This my query that supposed to get any digit after TOP
select regexp_substr('TIPTOP4152','(?<=TOP)\d+') sub from dual
But nothing to be displayed !

For the sake of argument, REGEXP_SUBSTR works too:
SQL> select regexp_substr('TIPTOP4152', 'TOP(\d+)', 1, 1, NULL, 1) nbr
from dual;
NBR
----
4152
SQL>

I'm not sure that Oracle supports lookbehind. Instead you should be able to do this pretty easily with regexp_replace
REGEXP_REPLACE('TIPTOP4152', '.*TOP(\d+)', '\1')

Related

Regexp_replace adding extra characters

I am using the following query in Oracle 11.2.0.3.0 / Toad for Oracle 11.6.1.6:
select regexp_replace('000010PARA197427'
,'([0-9]*)([A-Z]*)([0-9]*)'
,'\3-\2-\1') from dual
Rather than getting what I expected, 197427-PARA-000010.
I get 197427-PARA-000010-- as a result.
If I change the query to:
select regexp_replace('000010PARA197427'
,'([0-9]*)([A-Z]*)([0-9]*)'
,'\3-c\2-c\1') from dual
I then get 197427-cPARA-c000010-c-c for the result.
it's like all the literals are getting appended to the end of the result.
Any help would be much appreciated.
Not exactly sure why this is happening, but since you only have * quantifiers and no anchoring, maybe you're getting an empty match (or something like that).
Anchoring the pattern (/^...$/) seems to work. Using + rather than * for any of the quantifier also works for this sample.
SQL> select regexp_replace('000010PARA197427'
,'([0-9]+)([A-Z]*)([0-9]*)'
,'\3-\2-\1') foo from dual ;
FOO
------------------
197427-PARA-000010
SQL> select regexp_replace('000010PARA197427'
,'^([0-9]*)([A-Z]*)([0-9]*)$'
,'\3-\2-\1') foo from dual ;
FOO
------------------
197427-PARA-000010

How can I replace brackets to hyphens within Oracle REGEXP_REPLACE function?

I'm a newbie in regular expressions. I want to replace any text string symbols like (,),[,] to hyphens (for example):
SELECT REGEXP_REPLACE ('(<FIO>)', '(', '-') FROM dual;
This gives me ORA-12725 error.
Please, explain me, what's wrong?
Thanks.
To replace symbols, use the TRANSLATE function, it is less processor-intensive than regular expression functions:
SQL> SELECT translate ('(<FIO>)', '()[]', '----') replaced FROM dual;
REPLACED
--------
-<FIO>-
Regular expressions are more versatile and can do more complex things but are more expensive. In this case, replacing one character by another is done more efficiently by a specialized function. If you really want to use regular expressions, you could use REGEXP_REPLACE:
SQL> SELECT regexp_replace ('[(<FIO>)]', '[]()[]', '-', 1, 0) reg FROM dual;
REG
---------
--<FIO>--
Update: If you want to replace only the first symbol, translate won't work. Instead, use:
SQL> SELECT regexp_replace ('[(<FIO>)]', '[]()[]', '-', 1, 1) reg FROM dual;
REG
---------
-(<FIO>)]

How to get part of the string that matched with regular expression in Oracle SQL

Lets say I have following string: 'product=1627;color=45;size=7' in some field of the table.
I want to query for the color and get 45.
With this query:
SELECT REGEXP_SUBSTR('product=1627;color=45;size=7', 'color\=([^;]+);?') "colorID"
FROM DUAL;
I get :
colorID
---------
color=45;
1 row selected
.
Is it possible to get part of the matched string - 45 for this example?
One way to do it is with REGEXP_REPLACE. You need to define the whole string as a regex pattern and then use just the element you want as the replace string. In this example the ColorID is the third pattern in the entire string
SELECT REGEXP_REPLACE('product=1627;color=45;size=7'
, '(.*)(color\=)([^;]+);?(.*)'
, '\3') "colorID"
FROM DUAL;
It is possible there may be less clunky regex solutions, but this one definitely works. Here's a SQL Fiddle.
Try something like this:
SELECT REGEXP_SUBSTR(REGEXP_SUBSTR('product=1627;color=45;size=7', 'color\=([^;]+);?'), '[[:digit:]]+') "colorID"
FROM DUAL;
From Oracle 11g onwards we can specify capture groups in REGEXP_SUBSTR.
SELECT REGEXP_SUBSTR('product=1627;color=45;size=7', 'color=(\d+);', 1, 1, 'i', 1) "colorID"
FROM DUAL;

Oracle: How to use regexp_substr in this case

I have a table in Oracle where one of the column contains UserIds which are in the form of \. For eg "fin\george", "sales\andy" etc. How can I use REGEXP_SUBSTR function to get only the from the UserIds. ie I want to fetch only "george", "andy" etc. I have achieved the desired reult using SUBSTR function but I want to use REGEXP_SUBSTR in this case.
I tried doing this:
SELECT REGEXP_SUBSTR('fin\george','\[^\]+,') "UserName" FROM DUAL;
but it did'nt help. Can anyone please point out my mistake ?
I believe you want to use a regexp_replace with a backreference. I'm assuming that all the characters before and after the \ are alphabetic. If you allow numbers, you'd want to use the [[:alnum:]] rather than [[:alpha::].
1* SELECT REGEXP_replace('fin\george',
'([[:alpha:]]+\\)([[:alpha:]]+)$',
'\2') "UserName"
FROM DUAL
SQL> /
UserNa
------
george
SQL> SELECT REGEXP_SUBSTR('fin\george', '[^\]+', 1, 2) AS userId from dual;
USERID
------
george
See this Oracle Base article
select regexp_replace( 'fin\george', '.*\\', null ) from dual;
returns george.
The regex will match any character followed by the \ (which is escaped), as many times as possible (greedy).
So it will match everything up to the final \.
Then the matching string is replaced with null.
null is the default so
select regexp_replace('fin\george', '.*\\' ) from dual;
does the same thing
Same expression can extract filename from the end of pathname e.g.
select regexp_replace ('fin\fin2\fin3\fin4\george', '.*\\' ) from dual;
will also return george.
You have to use escaping: \\ instead of \
The easiest way (IMHO) to do this is the following:
SELECT REGEXP_SUBSTR('fin\george', '[^\\]+$') AS "UserName" FROM DUAL;
The issues with your original query were (a) that the \ character was not escaped and (b) there was an extraneous comma in the regular expression. I've used the end-of-string anchor $ here, assuming that there are not more than two elements delimited by \. If there are more than two, and you need only the second one, you can use the following:
SELECT REGEXP_SUBSTR('fin\george\ringo', '[^\\]+', 1, 2) AS "UserName"
FROM DUAL;
This tells Oracle to start looking at the first character of the string and return the second match.

How to Select a substring in Oracle SQL up to a specific character?

Say I have a table column that has results like:
ABC_blahblahblah
DEFGH_moreblahblahblah
IJKLMNOP_moremoremoremore
I would like to be able to write a query that selects this column from said table, but only returns the substring up to the Underscore (_) character. For example:
ABC
DEFGH
IJKLMNOP
The SUBSTRING function doesn't seem to be up to the task because it is position-based and the position of the underscore varies.
I thought about the TRIM function (the RTRIM function specifically):
SELECT RTRIM('listofchars' FROM somecolumn)
FROM sometable
But I'm not sure how I'd get this to work since it only seems to remove a certain list/set of characters and I'm really only after the characters leading up to the Underscore character.
Using a combination of SUBSTR, INSTR, and NVL (for strings without an underscore) will return what you want:
SELECT NVL(SUBSTR('ABC_blah', 0, INSTR('ABC_blah', '_')-1), 'ABC_blah') AS output
FROM DUAL
Result:
output
------
ABC
Use:
SELECT NVL(SUBSTR(t.column, 0, INSTR(t.column, '_')-1), t.column) AS output
FROM YOUR_TABLE t
Reference:
SUBSTR
INSTR
Addendum
If using Oracle10g+, you can use regex via REGEXP_SUBSTR.
This can be done using REGEXP_SUBSTR easily.
Please use
REGEXP_SUBSTR('STRING_EXAMPLE','[^_]+',1,1)
where STRING_EXAMPLE is your string.
Try:
SELECT
REGEXP_SUBSTR('STRING_EXAMPLE','[^_]+',1,1)
from dual
It will solve your problem.
You need to get the position of the first underscore (using INSTR) and then get the part of the string from 1st charecter to (pos-1) using substr.
1 select 'ABC_blahblahblah' test_string,
2 instr('ABC_blahblahblah','_',1,1) position_underscore,
3 substr('ABC_blahblahblah',1,instr('ABC_blahblahblah','_',1,1)-1) result
4* from dual
SQL> /
TEST_STRING POSITION_UNDERSCORE RES
---------------- ------------------ ---
ABC_blahblahblah 4 ABC
Instr documentation
Susbtr Documentation
SELECT REGEXP_SUBSTR('STRING_EXAMPLE','[^_]+',1,1) from dual
is the right answer, as posted by user1717270
If you use INSTR, it will give you the position for a string that assumes it contains "_" in it. What if it doesn't? Well the answer will be 0. Therefore, when you want to print the string, it will print a NULL.
Example: If you want to remove the domain from a "host.domain". In some cases you will only have the short name, i.e. "host". Most likely you would like to print "host". Well, with INSTR it will give you a NULL because it did not find any ".", i.e. it will print from 0 to 0. With REGEXP_SUBSTR you will get the right answer in all cases:
SELECT REGEXP_SUBSTR('HOST.DOMAIN','[^.]+',1,1) from dual;
HOST
and
SELECT REGEXP_SUBSTR('HOST','[^.]+',1,1) from dual;
HOST
Another possibility would be the use of REGEXP_SUBSTR.
In case if String position is not fixed then by below Select statement we can get the expected output.
Table Structure
ID VARCHAR2(100 BYTE)
CLIENT VARCHAR2(4000 BYTE)
Data-
ID CLIENT
1001 {"clientId":"con-bjp","clientName":"ABC","providerId":"SBS"}
1002
--
{"IdType":"AccountNo","Id":"XXXXXXXX3521","ToPricingId":"XXXXXXXX3521","clientId":"Test-Cust","clientName":"MFX"}
Requirement - Search ClientId string in CLIENT column and return the corresponding value. Like From "clientId":"con-bjp" --> con-bjp(Expected output)
select CLIENT,substr(substr(CLIENT,instr(CLIENT,'"clientId":"')+length('"clientId":"')),1,instr(substr(CLIENT,instr(CLIENT,'"clientId":"')+length('"clientId":"')),'"',1 )-1) cut_str from TEST_SC;
--
CLIENT cut_str
----------------------------------------------------------- ----------
{"clientId":"con-bjp","clientName":"ABC","providerId":"SBS"} con-bjp
{"IdType":"AccountNo","Id":"XXXXXXXX3521","ToPricingId":"XXXXXXXX3521","clientId":"Test-Cust","clientName":"MFX"} Test-Cust
Remember this if all your Strings in the column do not have an underscore
(...or else if null value will be the output):
SELECT COALESCE
(SUBSTR("STRING_COLUMN" , 0, INSTR("STRING_COLUMN", '_')-1),
"STRING_COLUMN")
AS OUTPUT FROM DUAL
To find any sub-string from large string:
string_value:=('This is String,Please search string 'Ple');
Then to find the string 'Ple' from String_value we can do as:
select substr(string_value,instr(string_value,'Ple'),length('Ple')) from dual;
You will find result: Ple