How to replace string using Regexp_Replace in oracle - oracle

I want to replace this:
"STORES/KOL#10/8/36#1718.00#4165570.00#119539388#PT3624496#9902001#04266#6721#PT3624496-11608091-1-55-STORES/KOL"
with this:
"STORES/KOL#10#8#36#1718.00#4165570.00#119539388#PT3624496#9902001#04266#6721#PT3624496-11608091-1-55-STORES/KOL"
basically this is conditional based replace I want to replace / with #
like STORES/KOL string should be STORES/KOL
but 10/8/36 string should be 10#8#36

This will replace the 2nd and 3rd / character with a #:
Oracle Setup:
CREATE TABLE test_data ( value ) AS
SELECT '"STORES/KOL#10/8/36#1718.00#4165570.00#119539388#PT3624496#9902001#04266#6721#PT3624496-11608091-1-55-STORES/KOL"'
FROM DUAL;
Query:
SELECT REGEXP_REPLACE(
value,
'^(.*?/.*?)/(.*?)/(.*)$',
'\1#\2#\3'
) AS replacement
FROM test_data
Output:
| REPLACEMENT |
| :---------------------------------------------------------------------------------------------------------------- |
| "STORES/KOL#10#8#36#1718.00#4165570.00#119539388#PT3624496#9902001#04266#6721#PT3624496-11608091-1-55-STORES/KOL" |
db<>fiddle here

Here is one option using REGEXP_REPLACE. We can try targeting the following regex pattern:
#(\d+)/(\d+)/(\d+)#
Then replace using the three capture groups, replacing the path separators with pound signs.
WITH yourTable AS (
SELECT 'STORES/KOL#10/8/36#1718.00#4165570.00#119539388#PT3624496#9902001#04266#6721#PT3624496-11608091-1-55-STORES/KOL' AS input FROM dual
)
SELECT
input,
REGEXP_REPLACE(input, '#(\d+)/(\d+)/(\d+)#', '#\1#\2#\3#') AS output
FROM yourTable;
Demo
Whether or not this regex replacement is specific enough/accurate for the rest of your data depends on that data, which you never showed us.

with s as (select '"STORES/KOL#10/8/36#1718.00#4165570.00#119539388#PT3624496#9902001#04266#6721#PT3624496-11608091-1-55-STORES/KOL"' str from dual)
select
replace(replace(str, '/', '#'), 'STORES#KOL', 'STORES/KOL') result_str_1,
regexp_replace(str, '(\d)/', '\1#') result_str_2
from s;

Related

How to use replace function in Oracle to remove a string?

In my table, I have data like PAT5DSA-(ALRP), LAR6DAOP-(RAH) etc..But I want to remove the strings like -(xxxx) or -(xxx) which can be any alphabets inside braces. Tried using the below:
select replace(:code,'-(Aa-Zz)',null) from employee;
But this didn't work..Can anyone please help?
We can do a regex replacement using REGEXP_REPLACE:
SELECT REGEXP_REPLACE('PAT5DSA-(ALRP)', '-\(.*?\)', '')
FROM dual;
PAT5DSA
The plain replace() doesn't understand patterns. You could use a regular expression replace, e.g.:
-- CTE for sample data
with cte (code) as (
select 'PAT5DSA-(ALRP)' from dual
union all
select 'LAR6DAOP-(RAH)' from dual
)
select code, regexp_replace(code, '-\(.*?\)$') as result
from cte;
CODE RESULT
-------------- --------------
PAT5DSA-(ALRP) PAT5DSA
LAR6DAOP-(RAH) LAR6DAOP
This will remove anything inside a pair of parentheses which is preceded by a dash, at the end of the original string. If the parentheses to be removed could be anywhere in the string then remove the $.
Use INSTR and SUBSTR:
WITH cteVals AS (SELECT 'PAT5DSA-(ALRP)' AS COL_VAL FROM DUAL UNION ALL
SELECT 'LAR6DAOP-(RAH)' AS COL_VAL FROM DUAL)
SELECT SUBSTR(COL_VAL, 1, INSTR(COL_VAL, '-')-1)
FROM cteVals;
Best of luck.

Oracle string operation to exclude specific characters based on delimiter

From the String ES-123456-PSA Spain-101, I need to extract only ES-123456-101 Delimiter position is fixed.
Tried REGEXP_SUBSTR('ES-123456-PSA Spain-101','[^-]+',2,3 ) which gives PSA Spain.
Is there a way to ignore those specific characters and returns rest of them.
If you want ES-123456-101 then use this:
SELECT REGEXP_REPLACE('ES-123456-PSA Spain-101', '[^-]+-', '', 1, 3 )
FROM dual;
If you want ES-12345-101 then could you explain the logic for 12345 not 123456? Typo or omit the last character?
you can also use subtr and instr
with t as
(
select 'ES-123456-PSA Spain-101' as text from dual
)
select substr(text,1,instr(text,'-',1,2)) -- ES-123456-
||substr(text,instr(text,'-',1,3)+1) -- 101
from t

Regexp_substr find string not matching a group of characters

I have a string like mystr = 'value1~|~value2~|~ ... valuen". I need it as one column separated on rows like this:
value1
value2
...
valuen
I'm trying this
select regexp_substr(mystr, '[^(~\|~)]', 1 , lvl) from dual, (select level as lvl from dual connect by level <= 5);
The problem is that ~|~ is not treated as a group, if I add ~ to anywhere in the string it gets separated; also () are treated as separators.
Any help is highly appreciated! Thanks! ~|~
Quick and dirty solution:
with t as (
select rtrim(regexp_substr('value1~|~value2~|~value3~|~value4', '(.+?)($|~\|~)', 1,level,''),'~|~')value from dual connect by level<10
) select * from t where value is not null;
[] signifies a single character match and [^] signifies a single character that does not match any of the contained characters.
So [^(~\|~)] will match any one character that is not ( or ~ or \ or | or ~ (again) or ).
What you want is a match that is terminated by your separator:
SELECT REGEXP_SUBSTR(
mystr,
'(.*?)(~\|~)',
1,
LEVEL,
NULL,
1
)
FROM DUAL
CONNECT BY LEVEL < REGEXP_COUNT( mystr, '(.*?)(~\|~)' );
(or if you cannot have zero-width matches, you can use the regular expression '(.+?)(~\|~)' and <= in the CONNECT BY clause.)
This will parse the delimited list and the format of the regex will handle NULL list elements should they occur as shown in the example.
SQL> with tbl(str) as (
select 'value1~|~value2~|~~|~value4' from dual
)
select regexp_substr(str, '(.*?)(~\|~|$)', 1, level, NULL, 1) parsed
from tbl
connect by level <= regexp_count(str, '~\|~')+1;
PARSED
--------------------------------
value1
value2
value4
SQL>

Replace multiple substrings with one expression in Oracle SQL

I would like to delete multiple substrings from one column. I tried the replace function with the following code:
select replace('testetstestetststst', 'test'||'et'||'s', '')
from dual;
My expected result is ttt, but I get tstst.
In R it works with:
gsub("test|et|s", "", "testetstestetststst")
How can I replace many different substrings with nothing ('') in a column in clob format in Oracle SQL?
You need the REGEXP version of REPLACE:
select regexp_replace('testetstestetststst', 'test|et|s', '')
from dual;
In your code, you are concatenating strings, instead of using an OR operator; that is, your code is equivalent to
select replace('testetstestetststst', 'testets', '')
from dual;
Rather than using regular expressions, you can nest multiple REPLACE functions:
SELECT REPLACE(
REPLACE(
REPLACE(
'testetstestetststst',
'test'
),
'et'
),
's'
)
FROM DUAL;
We can directly use decode function.
select decode(job,'clerk','1','manager','2','salesman','3',4) from emp;
This will replace clerk with 1,manager with 2,salesman with 3 and other values with 4.

trim value till specified string in oracle pl/sql

i want to trim value of the given string till specified string in oracle pl/sql.
some thing like below.
OyeBuddy$$flex-Flex_Image_Rotator-1443680885520.
In the above string i want to trim till $$ so that i will get "flex-Flex_Image_Rotator-1443680885520".
You can use different ways; here are two methods, with and without regexp:
with test(string) as ( select 'OyeBuddy$$flex-Flex_Image_Rotator-1443680885520.' from dual)
select regexp_replace(string, '(.*)(\$\$)(.*)', '\3')
from test
union all
select substr(string, instr(string, '$$') + length('$$'))
from test
You want to do a SUBSTR where the starting position is going to be the position of '$$' + 2 . +2 is because the string '$$' is of length 2, and we don't want to include that string in the result.
Something like -
SELECT SUBSTR (
'ABCDEF$$some_big_text',
INSTR ('ABCDEF$$some_big_text', '$$') + 2)
FROM DUAL;

Resources