Oracle regexp to ignore repeating characters - sql

I've a string like:
hheelllloo wwoorrlldd !!
that should return hello world!
and my try for the above is
SELECT regexp_substr('hheelllloo wwoorrlldd !!', '.', LEVEL*2-1)l_val
FROM dual
CONNECT BY LEVEL <= LENGTH('hheelllloo wwoorrlldd !!')/2;
But its not the way i needed and the logic is not correctly used.
I've also tried using '(\w)\1'
My expected result in a sample data:
WITH t AS
( SELECT 'hheelllloo wwoorrlldd!!' AS word FROM dual
UNION
SELECT 'hellow world!' FROM dual
UNION
SELECT 'ootthheerrss' FROM dual
UNION
SELECT 'ootthheeerrss' FROM dual
)
SELECT * FROM t;
output should looks like:
hello world! --expression applied
hellow world! -- not needed for non-repeated characters
others --expression applied
otheers --applied and extra `e` considered as non-repeated.
Can I make the whole in a single query., or the first one?
Thanks in advance and this is only for my practice and to know different logic.

You can use regexp_replace() regular expression function with back reference:
SQL> WITH t1(col) AS (
2 select 'hheelllloo wwoorrlldd!!' from dual union all
3 select 'hellow world!' from dual union all
4 select 'ootthheerrss' from dual union all
5 select 'ootthheeerrss' from dual
6 )
7 select regexp_replace(col, '(.)\1', '\1') as res
8 from t1
9 ;
RES
--------------
hello world!
helow world!
others
otheers

And
select regexp_replace('A;A;B;B', '(.)\1', '\1')
from `dual`
Output:
A;B ????????
I have this answer.

Related

Oracle db - remove ,, from email address

I'm running below code and getting below results but I want to remove ,, and after ,, texts from email address and that email address should show in UPPER(PT_PARTNER_EMAIL) VALID_EMAIL_ID column.
How can I achieve this?
select party_id, pt_partner_id, pt_partner_email, upper(pt_partner_email) valid_email_id
from odi_ods_partner_dim
where length(pt_partner_email) > 3
PARTY_ID PT_PARTNER_ID PT_PARTNER_EMAIL VALID_EMAIL_ID
3223218102E17 10101363 DEEPAKSKORI#GMAIL.COM,,ALL DEEPAKSKORI#GMAIL.COM,,ALL
5951118102E17 12059043 jalaj79#gmail.com,, JALAJ79#GMAIL.COM,,
1113418102E17 12059044 hassanselim1993#gmail.com,, HASSANSELIM1993#GMAIL.COM,,
2579321752017 36419244 drshetty#surgicare.co.in,, DRSHETTY#SURGICARE.CO.IN,,
please suggest how can I achive this.
try using these
Upper - Make all to upper case
https://www.techonthenet.com/oracle/functions/upper.php
Instr - find the position of ,,
https://www.techonthenet.com/oracle/functions/instr.php
Substr - Cut from start to where ,, is
https://www.techonthenet.com/oracle/functions/substr.php
e.g.
select upper( substr('wo++' , 1 , instr('wo++' , '++' )-1 ) ) from dual
--result WO
You can check if the ,, substring exists using the INSTR function and then, if it does, remove it using SUBSTR and INSTR:
SELECT party_id,
pt_partner_id,
pt_partner_email,
UPPER(
CASE INSTR(pt_partner_email, ',,')
WHEN 0
THEN pt_partner_email
ELSE SUBSTR(pt_partner_email, 1, INSTR(pt_partner_email, ',,') - 1)
END
) AS valid_email_id
FROM odi_ods_partner_dim
WHERE LENGTH(pt_partner_email) > 3
Which, for the sample data:
CREATE TABLE odi_ods_partner_dim (PARTY_ID, PT_PARTNER_ID, PT_PARTNER_EMAIL) AS
SELECT '3223218102E17', 10101363, 'DEEPAKSKORI#EXAMPLE.COM,,ALL' FROM DUAL UNION ALL
SELECT '5951118102E17', 12059043, 'jalaj79#example.com,,' FROM DUAL UNION ALL
SELECT '1113418102E17', 12059044, 'hassanselim1993#example.com,,' FROM DUAL UNION ALL
SELECT '2579321752017', 36419244, 'drshetty#example.co.in,,' FROM DUAL UNION ALL
SELECT 'ABC1234567890', 12345678, 'example#example.com' FROM DUAL;
Note: this includes an extra rows which does not contain ,,.
Outputs:
PARTY_ID
PT_PARTNER_ID
PT_PARTNER_EMAIL
VALID_EMAIL_ID
3223218102E17
10101363
DEEPAKSKORI#EXAMPLE.COM,,ALL
DEEPAKSKORI#EXAMPLE.COM
5951118102E17
12059043
jalaj79#example.com,,
JALAJ79#EXAMPLE.COM
1113418102E17
12059044
hassanselim1993#example.com,,
HASSANSELIM1993#EXAMPLE.COM
2579321752017
36419244
drshetty#example.co.in,,
DRSHETTY#EXAMPLE.CO.IN
ABC1234567890
12345678
example#example.com
EXAMPLE#EXAMPLE.COM
db<>fiddle here
Here is one option:
with test1 as(
select 'DEEPAKSKORI#GMAIL.COM,,ALL' VALID_EMAIL_ID from dual union all
select 'jalaj79#gmail.com,,' VALID_EMAIL_ID from dual union all
select 'hassanselim1993#gmail.com,,' VALID_EMAIL_ID from dual union all
select 'drshetty#surgicare.co.in,,' VALID_EMAIL_ID from dual
)
select upper(substr(VALID_EMAIL_ID,1,instr(VALID_EMAIL_ID,',,')-1)) from test1
Result:
DEEPAKSKORI#GMAIL.COM
JALAJ79#GMAIL.COM
HASSANSELIM1993#GMAIL.COM
DRSHETTY#SURGICARE.CO.IN

How to remove one or more instances of '?*' in a string using REGEXP_REPLACE function in oracle?

I'm getting the characters '?*' one to three times in a column called Line. I am required to remove these characters. How do I do it using Replace or REGEXP_REPLACE?
SELECT
Line, REGEXP_REPLACE(LINE,'[?*]','')--([^\+]+)
FROM
TABLE
WHERE
INSTR(LINE,'?*') != 0;
where
REGEXP_REPLACE(LINE,'\?*','') replaces the ? alone and leaves the * untouched.
REGEXP_REPLACE(LINE,'?*','') replaces nothing.
REGEXP_REPLACE(LINE,'[?*]','') replaces all ?s and all *s. I am only replacing when ? and * comes together as ?*.
If you need the remove the string '?*', you can use replace:
SQL> with test(string) as (
2 select 'aa?*b?' from dual union all
3 select 'a*a?*??b?' from dual union all
4 select 'a*a??b???c*?**cc' from dual union all
5 select 'aa?b?*?cc?d??*?*?' from dual
6 )
7 select string, replace(string, '?*', '') as result
8 from test;
STRING RESULT
----------------- ---------------
aa?*b? aab?
a*a?*??b? a*a??b?
a*a??b???c*?**cc a*a??b???c**cc
aa?b?*?cc?d??*?*? aa?b?cc?d??
Use (\?\*) as pattern :
with tab(line) as
(
select 'abc?*ghh*?g?l*' from dual union all
select '?*U?KJ*H' from dual union all
select '*R5?4*&t?*frg?*' from dual
)
select regexp_replace(line,'(\?\*)') as "Result String"
from tab;
Result String
-------------
abcghh*?g?l*
U?KJ*H
*R5?4*&tfrg
Demo

Get substring with REGEXP_SUBSTR

I need to use regexp_substr, but I can't use it properly
I have column (l.id) with numbers, for example:
1234567891123!123 EXPECTED OUTPUT: 1234567891123
123456789112!123 EXPECTED OUTPUT: 123456789112
12345678911!123 EXPECTED OUTPUT: 12345678911
1234567891123!123 EXPECTED OUTPUT: 1234567891123
I want use regexp_substr before the exclamation mark (!)
SELECT REGEXP_SUBSTR(l.id,'[%!]',1,13) from l.table
is it ok ?
You can try using INSTR() and substr()
DEMO
select substr(l.id,1,INSTR(l.id,'!', 1, 1)-1) from dual
You want to remove the exclamation mark and all following characters it seems. That is simply:
select regexp_replace(id, '!.*', '') from mytable;
Look at it like a delimited string where the bang is the delimiter and you want the first element, even if it is NULL. Make sure to test all possibilities, even the unexpected ones (ALWAYS expect the unexpected)! Here the assumption is if there is no delimiter you'll want what's there.
The regex returns the first element followed by a bang or the end of the line. Note this form of the regex handles a NULL first element.
SQL> with tbl(id, str) as (
select 1, '1234567891123!123' from dual union all
select 2, '123456789112!123' from dual union all
select 3, '12345678911!123' from dual union all
select 4, '1234567891123!123' from dual union all
select 5, '!123' from dual union all
select 6, '123!' from dual union all
select 7, '' from dual union all
select 8, '12345' from dual
)
select id, regexp_substr(str, '(.*?)(!|$)', 1, 1, NULL, 1)
from tbl
order by id;
ID REGEXP_SUBSTR(STR
---------- -----------------
1 1234567891123
2 123456789112
3 12345678911
4 1234567891123
5
6 123
7
8 12345
8 rows selected.
SQL>
If you like to use REGEXP_SUBSTR rather than regexp_replace then you can use
SELECT REGEXP_SUBSTR(l.id,'^\d+')
assuming you have only numbers before !
If I understand correctly, this is the pattern that you want:
SELECT REGEXP_SUBSTR(l.id,'^[^!]+', 1)
FROM (SELECT '1234567891123!123' as id from dual) l

Is there any possibility of using "? =" and "?<=" qualifiers inside the regular expressions in oracle sql?

Is there any possibility of using ?= and ?<= qualifiers inside the regular expressions in oracle sql?
You can use TRANSLATE, but in my opinion is not easy to maintain. You also can use regexp_replace function. Basically, you are replacing everyting but the first letter of each word.
-- Solution 1
WITH T AS (
SELECT 'Fredy Mercury' str FROM dual UNION ALL
SELECT 'Hello World' FROM dual UNION ALL
SELECT 'Abc Def Ghi Klm Opq' FROM dual UNION ALL
SELECT 'As far as I know' FROM dual
)
SELECT str,
TRANSLATE(INITCAP(str)
,'ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz'
,'ABCDEFGHIJKLMNOPQRSTUVWXYZ')
FROM T;
-- Solution 2
WITH T AS (
SELECT 'Fredy Mercury' str FROM dual UNION ALL
SELECT 'Hello World' FROM dual UNION ALL
SELECT 'Abc Def Ghi Klm Opq' FROM dual UNION ALL
SELECT 'As far as I know' FROM dual
)
SELECT str, UPPER(regexp_replace(str,'(\w{1})\w*(\W+|$)','\1')) FROM T;
Hopefully, this is helpful.

How to cut everything after a specific character, but in case string doesn't contain it do nothing?

Let's say i have following data:
fjflka, kdjf
ssssllkjf fkdsjl
skfjjsld, kjl
jdkfjlj, ksd
lkjlkj hjk
I want to cut out everything after ',' but in case the string doesn't contain this character, it wont do anything, if i use substr and cut everything after ',' the string which doesn't contain this character shows as null. How do i achieve this? Im using oracle 11g.
This should work. Simply use regexp_substr
with t_view as (
select 'fjflka, kdjf' as text from dual union
select 'ssssllkjf fkdsjl' from dual union
select 'skfjjsld, kjl' from dual union
select 'jdkfjlj, ksd' from dual union
select 'lkjlkj hjk' from dual
)
select text,regexp_substr(text,'[^,]+',1,1) from t_view;
Assuming your table :
SQL> desc mytable
s varchar2(100)
you may use:
select decode(instr(s,','),0,s,substr(s,1,instr(s,',')-1)) from mytable;
demo
Well the below query works as per your requirement.
with mytable as
(select 'aaasfasf wqwe' s from dual
union all
select 'aaasfasf, wqwe' s from dual)
select s,substr(s||',',1,instr(s||',',',')-1) from mytable;