How to give argument for a repeating character in snowflake regex - sql

My string is a comment that looks like:
***z|Samuel|Amount:15|Frequency:1
I want to use regex to filter all such rows out of a data base, my query is below
select
ID,
COMMENT,
max(case when lower(COMMENT) Rlike '\*+z\|Samuel\|Amount:[0-9]+\|Frequency:[0-9]+'
then 1 else 0 end) as indicator
from Table_Name group by 1,2
But this gives me an error:
Invalid regular expression: '*+z|Samuel|Amount:[0-9]+|Frequency:[0-9]+', no argument for repetition operator: *
Does anyone know how to navigate through this?

Using '[*]+z[|]Samuel[|]Amount:[0-9]+[|]Frequency:[0-9]+':
CREATE OR REPLACE TEMPORARY TABLE t AS
SELECT '***z|Samuel|Amount:15|Frequency:1' AS COMMENT;
SELECT *
FROM t
WHERE RLIKE (t.COMMENT, '[*]+z[|]Samuel[|]Amount:[0-9]+[|]Frequency:[0-9]+', 'i');
Output:
Alternatively the original \ should be doubled or the string not wrapped with ':
'\*+z\|Samuel\|Amount:[0-9]+\|Frequency:[0-9]+'
=>
'\\*+z\\|Samuel\\|Amount:[0-9]+\\|Frequency:[0-9]+'
$$\*+z\|Samuel\|Amount:[0-9]+\|Frequency:[0-9]+$$
Matching Characters That Are Metacharacters
If you are using the regular expression in a single-quoted string constant, you must escape the backslash with a second backslash (e.g. \., \*, \?, etc.).
SELECT COMMENT,
RLIKE (t.COMMENT, '[*]+z[|]Samuel[|]Amount:[0-9]+[|]Frequency:[0-9]+', 'i') AS "[]",
RLIKE (t.COMMENT, $$\*+z\|Samuel\|Amount:[0-9]+\|Frequency:[0-9]+$$, 'i') AS "$$",
RLIKE (t.COMMENT, '\\*+z\\|Samuel\\|Amount:[0-9]+\\|Frequency:[0-9]+', 'i') AS "\\"
FROM t;
Output:

Related

How do I use an ORACLE REGEX function to remove all leading and trailing line break characters and spaces?

How do I use an ORACLE REGEX function to remove all leading and trailing line break characters and spaces?
For example, assume I have the following string where refers to actual invisible carriage return line feed characters. Here's the input:
"
SELECT *
FROM
TABLE
"
And here's the desire output:
"SELECT *
FROM
TABLE"
This would do it if regex_replace() is a requirement:
select regexp_replace('
SELECT *
FROM
TABLE
', '^\s*|\s*$', '') as hello
from dual
See https://www.techonthenet.com/oracle/functions/regexp_replace.php for documentation.
A single regexp_replace is sufficient, eg.
select regexp_replace('
select frut
from prut
','^[[:space:]]*(.*[^[:space:]])[[:space:]]*$','\1',1,1,'mn') from dual;
results in
select frut
from prut

PostgreSQL regexp replace function with condition

There is a PostgreSQL table. This table has a field which contains the queries of the stored procedures as string.
I am looking for a regexp replace solution which I am able to remove the part of the string with but only in that cases where the string contains 'tmp'.
Example string inputs:
...from schema1.table_1...
...from schema1.table_1_tmp...
...from schema1.table_2...
...from schema1.table_2_tmp...
Aim:
...from schema1.table_1...
...from table_1_tmp...
...from schema1.table_2...
...from table_2_tmp...
schema1 is a static value, only the table names are different. Some of them contains tmp substring, some of them not.
If it contains tmp, we should remove the schema1 string.
You could use regexp_replace() as follows:
regexp_replace(mycol, '\sschema1\.(\w+_tmp)\s', ' \1 ')
Regex breakdown:
\s a space
schema1\. litteral string "schema1."
( beginning of a capturing group
\w+ at many alphanumeric characters as possible (including "_")
_tmp litteral string "_tmp"
) end of the capturing group
\s a space
When the string matches the regex, the matching expression is replaced by: a space, then the captured part, then another space.
Demo on DB Fiddle:
with t as (
select '... from schema1.table_1_tmp ...' mycol
union all select '... from schema1.table_2 ...'
)
select mycol, regexp_replace(mycol, '\sschema1\.(\w+_tmp)\s', ' \1 ') newcol from t
mycol | newcol
:------------------------------- | :---------------------------
... from schema1.table_1_tmp ... | ... from table_1_tmp ...
... from schema1.table_2 ... | ... from schema1.table_2 ...
You really need to update your Postgres version; version 8.3.x reached end-of-life in Feb-2013. However, the #GMB answer should work as all the appropriate regexp functions do exist in it. However, you can also try the replace function.
with test_tab (tbl) as
( values ('...from schema1.table_1...')
, ('...from schema1.table_1_tmp...')
, ('...from schema1.table_2...')
, ('...from schema1.table_2_tmp...')
)
select replace(tbl,'schema1.','') "Without Schema"
from test_tab
where tbl ilike '%schema1%_tmp%';

Get the data from a string between double quotes in Oracle

I have a string with double quotes inside.
EG:
<cosmtio :ff "intermit"ksks>
I need the data between the ""
I have tried the regexp_substr but still couldn't get the value between double-quotes.
We could try using REGEXP_REPLACE here:
SELECT
string,
REGEXP_REPLACE(string, '.*"([^"]+)".*', '\1') AS quoted_term
FROM yourTable;
Data:
WITH yourTable AS (
SELECT '<cosmtio :ff "intermit"ksks>' AS string FROM dual
)
Demo
Another option, using REGEXP_SUBSTR:
SELECT
string,
TRIM(BOTH '"' FROM REGEXP_SUBSTR(string, '".*"'))
FROM yourTable;
But this approach requires nesting two function calls, which means it might not outperform the REGEXP_REPLACE version.
You need to use REGEXP_SUBSTR:
SELECT REGEXP_SUBSTR('<cosmtio :ff "intermit"ksks>', '"([^"]+)"', 1, 1, NULL, 1) AS Result FROM DUAL
See the online demo.
The regex is simple: "([^"]+)" matches ", then captures any 1+ chars other than " into Group 1 and then matches ". The last argument is 1 telling Oracle REGEXP_SUBSTR to return the Group 1 values. The first (position) and the second (occurrence) arguments are default, 1. NULL means no specific options need to be passed to the regex engine.
You can try the following:
SELECT REGEXP_REPLACE('<cosmtio :ff "intermit"ksks>', '^[^"]*("([^"]*)")?.*', '\2') FROM dual
It is possible with regexp_substr as following:
Select
regexp_substr('<cosmtio :ff "intermit"ksks>', '[^"]+', 1, 2)
from dual;
Cheers!!

Select statement with column contains '%'

I want to select names from a table where the 'name' column contains '%' anywhere in the value. For example, I want to retrieve the name 'Approval for 20 % discount for parts'.
SELECT NAME FROM TABLE WHERE NAME ... ?
You can use like with escape. The default is a backslash in some databases (but not in Oracle), so:
select name
from table
where name like '%\%%' ESCAPE '\'
This is standard, and works in most databases. The Oracle documentation is here.
Of course, you could also use instr():
where instr(name, '%') > 0
One way to do it is using replace with an empty string and checking to see if the difference in length of the original string and modified string is > 0.
select name
from table
where length(name) - length(replace(name,'%','')) > 0
Make life easy on yourselves and just use REGEXP_LIKE( )!
SQL> with tbl(name) as (
select 'ABC' from dual
union
select 'E%FS' from dual
)
select name
from tbl
where regexp_like(name, '%');
NAME
----
E%FS
SQL>
I read the documentation mentioned by Gordon. The relevent sentence is:
An underscore (_) in the pattern matches exactly one character (as opposed to one byte in a multibyte character set) in the value
Here was my test:
select c
from (
select 'a%be' c
from dual) d
where c like '_%'
The value a%be was returned.
While the suggestions of using instr() or length in the other two answers will lead to the correct answer, they will do so slowly. Filtering on function results simply take longer than filtering on fields.

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 |