oracle sql regexp_replace - sql

I have a table that has the values like this.
ExpTable
+--------+
|expCol |
+--------+
|abc.abc |
|bcd.123 |
|efg.#/. |
+--------+
And what I wanted is that when the character after the period is a letter or number, the output will add a space after the dot like this:
Expected Output
+--------+
|expCol |
+--------+
|abc. abc|
|bcd. 123|
|efg.#/. | --the value here stays the same because after the period is not a letter/number
+--------+
I tried:
SELECT REGEXP_REPLACE(expCol, '.', '. ') from expTable WHERE /*condition*/
And as expected, everything including the last value 'efg.#/.' has got a space after the period. I dont know what to put in the WHERE clause.

You could try this. It searches for a . followed by a word character, and replaces it with a dot ., then a space and the matched character.
select REGEXP_REPLACE(expCol, '\.(\w)','. \1') FROM ExpTable;
if you only want the first such occurrence to be replaced, you could specify it.
REGEXP_REPLACE(expCol, '\.(\w)','. \1',1,1)
Only thing to note is this would match a number,alphabet and underscore as well, if you don't want to consider "_" , use [[:alnum:]] or [a-zA-Z0-9] in place of \w
Demo

SELECT REGEXP_REPLACE(expCol, '\.([a-zA-Z0-9])', '. \1') AS expCol FROM expTable
OR
SELECT REGEXP_REPLACE(expCol, '[.]([a-zA-Z0-9])', '. \1') AS expCol FROM expTable
Output
EXPCOL
abc. abc
bcd. 123
efg.#/.
LiveDemo
http://sqlfiddle.com/#!4/0a6e0/31

You can try this.
. is a keyword in regex so you need put \ in front of it
SELECT REGEXP_REPLACE(expCol, '\.(\w)', '. \1') from T
sqlfiddle :http://sqlfiddle.com/#!4/94ffec/1

Related

SQL - trimming values before bracket

I have a column of values where some values contain brackets with text which I would like to remove. This is an example of what I have and what I want:
CREATE TABLE test
(column_i_have varchar(50),
column_i_want varchar(50))
INSERT INTO test (column_i_have, column_i_want)
VALUES ('hospital (PWD)', 'hopistal'),
('nursing (LLC)','nursing'),
('longterm (AT)', 'longterm'),
('inpatient', 'inpatient')
I have only come across approaches that use the number of characters or the position to trim the string, but these values have varying lengths. One way I was thinking was something like:
TRIM('(*',col1)
Doesn't work. Is there a way to do this in postgres SQL without using the position? THANK YOU!
If all the values contain "valid" brackets, then you may use split_part function without any regular expressions:
select
test.*,
trim(split_part(column_i_have, '(', 1)) as res
from test
column_i_have | column_i_want | res
:------------- | :------------ | :--------
hospital (PWD) | hopistal | hospital
nursing (LLC) | nursing | nursing
longterm (AT) | longterm | longterm
inpatient | inpatient | inpatient
db<>fiddle here
You can replace partial patterns using regular expressions. For example:
select *, regexp_replace(v, '\([^\)]*\)', '', 'g') as r
from (
select '''hospital (PWD)'', ''nursing (LLC)'', ''longterm (AT)'', ''inpatient''' as v
) x
Result:
r
-------------------------------------------------
'hospital ', 'nursing ', 'longterm ', 'inpatient'
See example at db<>fiddle.
Could it be as easy as:
SELECT SUBSTRING(column_i_have, '\w+') AS column_i_want FROM test
See demo
If not, and you still want to use SUBSTRING() to get upto but exclude paranthesis, then maybe:
SELECT SUBSTRING(column_i_have, '^(.+?)(?:\s*\(.*)?$') AS column_i_want FROM test
See demo
But if you really are looking upto the opening paranthesis, then maybe just use SPLIT_PART():
SELECT SPLIT_PART(column_i_have, ' (', 1) AS column_i_want FROM test
See demo

SQL Server Replace with multiple SUBSTRING SSMS

I would like to change multiple substrings at once for example
'0100001000100'
The desired output.
' | ABC | | | | DFG | | | HIG | |'
REPLACE(SUBSTRING([column],1,1),' 1 ' ,' XYZ '),SUBSTRING([column],2,1),' 1 ' ,' zzz ')....
but does not work.
It's extremely unclear how you mean your input to turn to your desired output. However, hopefully this will clear up your confusion about the REPLACE function.
REPLACE(targetstring, str1, str2) will find each occurrence of str1 in targetstring and replace it with str2. So REPLACE('I know John and John knows me', 'John', 'Fred') would result in the string 'I know Fred and Fred knows me'.
To chain REPLACEs together, so that the output from the first REPLACE is used as the target for the next replace, you need a structure like this:
REPLACE(
REPLACE(
REPLACE(
'I know Fred and Fred knows me', 'Fred', 'Bill'
), 'know', 'like'
), 'and', 'but'
)
Next point: if you want to string together your replacement results on each character, you need to not chain the REPLACEs but instead join them with +:
REPLACE(SUBSTRING([column],1,1),'1','XYZ')
+
REPLACE(SUBSTRING([column],2,1),'1','zzz')
+ ...

format string with comma

I am getting a string output as : A B C D
I want to get it converted to: A,B,C and D.
Is there and function in PostgreSQL to do it.
Try this:
select REPLACE('A B C D', ' ', ',')
And to replace A,B,C,D to A,B,C and D use the following:
select substring('A,B,C,D',1,
length('A,B,C,D')-position(',' in reverse('A,B,C,D')))
|| ' and ' ||
substring('A,B,C,D',length('A,B,C,D')-position(',' in reverse('A,B,C,D'))+2);
You can combine the above with replace to make it single query.
I would use a two-step approach. The first step replaces all spaces with a comma. And then the last comma is replaced with the AND using a regular expression:
regexp_replace(replace('A B C D',' ',','), '(.*)(,)(\w+)$', '\1 and \3')
Online example
No need to complicate things.
A single regex function that capture each element and lets you do whatever you want with it.
select regexp_replace(mycol, '(\S)+\s+(\S+)\s+(\S)\s+(\S+)','\1,\2,\3 and \4')
from mytab
-
+----------------+
| regexp_replace |
+----------------+
| A,B,C and D |
+----------------+
SQL Fiddle

SQL: Select rows that contain a word

The goal is to select all rows that contain some specific word, can be in the beginning or the end of the string and/or surrounded by white-space, should not be inside other word, so to speak.
Here are couple rows in my database:
+---+--------------------+
| 1 | string with test |
+---+--------------------+
| 2 | test string |
+---+--------------------+
| 3 | testing stringtest |
+---+--------------------+
| 4 | not-a-test |
+---+--------------------+
| 5 | test |
+---+--------------------+
So in this example, selecting word test, should return rows 1, 2 and 5.
Problem is that for some reason, SELECT * FROM ... WHERE ... RLIKE '(\s|^)test(\s|$)'; returns 0 rows.
Where am I wrong and maybe, how it could be done better?
Edit: Query should also select the row with just a word test.
The answer to my first question is:
I haven't escaped special characters, so \s should be \\s.
Working query: SELECT * FROM ... WHERE ... RLIKE '(\\s|^)test(\\s|$)';. (or just a space ( |^)/( |$), also works)
Hi you could grab with trailing space and with leading space
SELECT * from new_table
where text RLIKE(' test')
union
SELECT * from new_table
where text RLIKE('test ')
REGEXP_INSTR() function, which's is an extension of the INSTR() function, might be used for version 10.0.5+ case-insensitively as default :
SELECT *
FROM t
WHERE REGEXP_INSTR(str, 'TeSt ')>0
OR REGEXP_INSTR(str, ' tESt')>0
Demo
SELECT * FROM ...
WHERE ... LIKE 'test';
This should do the trick.
Is this what you want?
SELECT * FROM ... WHERE ... LIKE
'%test%';
Use word boundary tests:
Before MySQL 8.0, and in MariaDB:
WHERE ... REGEXP '[[:<:]]test[[:>:]]'
MySQL 8.0:
WHERE ... REGEXP '\btest\b'
(If that does not work, double up the backslashes; this depends on whether the client is collapsing backslashes before MySQL gets them.)
Note that this solution will also work with punctuation such as the comma in "foo, test, bar"

Delete certain character based on the preceding or succeeding character - ORACLE

I have used REPLACE function in order to delete email addresses from hundreds of records. However, as it is known, the semicolon is the separator, usually between each email address and anther. The problem is, there are a lot of semicolons left randomly.
For example: the field:
123#hotmail.com;456#yahoo.com;789#gmail.com;xyz#msn.com
Let's say that after I deleted two email addresses, the field content became like:
;456#yahoo.com;789#gmail.com;
I need to clean these fields from these extra undesired semicolons to be like
456#yahoo.com;789#gmail.com
For double semicolons I have used REPLACE as well by replacing each ;; with ;
Is there anyway to delete any semicolon that is not preceded or following by any character?
If you only need to replace semicolons at the start or end of the string, using a regular expression with the anchor '^' (beginning of string) / '$' (end of string) should achieve what you want:
with v_data as (
select '123#hotmail.com;456#yahoo.com;789#gmail.com;xyz#msn.com' value
from dual union all
select ';456#yahoo.com;789#gmail.com;' value from dual
)
select
value,
regexp_replace(regexp_replace(value, '^;', ''), ';$', '') as normalized_value
from v_data
If you also need to replace stray semicolons from the middle of the string, you'll probably need regexes with lookahead/lookbehind.
You remove leading and trailing characters with TRIM:
select trim(both ';' from ';456#yahoo.com;;;789#gmail.com;') from dual;
To replace multiple characters with only one occurrence use REGEXP_REPLACE:
select regexp_replace(';456#yahoo.com;;;789#gmail.com;', ';+', ';') from dual;
Both methods combined:
select regexp_replace( trim(both ';' from ';456#yahoo.com;;;789#gmail.com;'), ';+', ';' ) from dual;
regular expression replace can help
select regexp_replace('123#hotmail.com;456#yahoo.com;;456#yahoo.com;;789#gmail.com',
'456#yahoo.com(;)+') as result from dual;
Output:
| RESULT |
|-------------------------------|
| 123#hotmail.com;789#gmail.com |