How Can I Extract String in Oracle - oracle

I would like to extract following string in Oracle. How can I do that?
Original String: 011113584378(+) CARD, STAFF
Expected String: STAFF CARD

I presume you have the luxury of writing a PL/SQL function? Then just use "SUBSTR", and/or "INSTR", and || concatenation operator to parse your input.
Here is an example:
https://www.techonthenet.com/oracle/questions/parse.php
...The field may contain the following value:
F:\Siebfile\YD\S_SR_ATT_1-60SS_1-AM3L.SAF
In this case, I need to return the value of '1-60SS', as this is the value that resides between the 3rd and 4th underscores.
SOLUTION:
create or replace function parse_value (pValue varchar2)
return varchar2
is
v_pos3 number;
v_pos4 number;
begin
/* Return 3rd occurrence of '_' */
v_pos3 := INSTR (pValue, '_', 1, 3) + 1;
/* Return 4rd occurrence of '_' */
v_pos4 := INSTR (pValue, '_', 1, 4);
return SUBSTR (pValue, v_pos3, v_pos4 - v_pos3);
end parse_value;

Ok, I'll bite. This example uses REGEXP_REPLACE to describe the string, saving the parts you need in order to rearrange them before returning them. It would be better if you showed some real-world examples of the data you are dealing with as I can only guarantee this example will work with the one line you provided.
The regular expression matches any characters starting at the beginning of the string and ending with a close paren-space. The next set of any characters up to but not including the comma-space is "remembered" by enclosing them in parens. This is called a captured group. The next captured group is the set of characters after that comma-space separator until the end of the line (the dollar sign). The captured groups are referred to by their order from left to right. The 3rd argument is the string to return, which is the 2nd and 1st captured groups, in that order, separated by a space.
SQL> with tbl(str) as (
select '+011113584378(+) CARD, STAFF' from dual
)
select regexp_replace(str, '^.*\) (.*), (.*)$', '\2 \1') formatted
from tbl;
FORMATTED
----------
STAFF CARD
SQL>

Related

REGEXP_LIKE Oracle equivalent to count characters in Snowflake

I am trying to come up with an equivalent of the below Oracle statement in Snowflake. This would check if the different parts of the string separated by '.' matches the number of characters in the REGEXP_LIKE expression. I have come up with a rudimentary version to perform the check in Snowflake but I am sure there's a better and cleaner way to do it. I am looking to come up with a one-liner regular expression check in Snowflake similar to Oracle. Appreciate your help!
-- Oracle
SELECT -- would return True
CASE
WHEN REGEXP_LIKE('AB.XYX.12.34.5670.89', '^\w{2}\.\w{3}\.\w{2}') THEN 'True'
ELSE NULL
END AS abc
FROM DUAL
-- Snowflake
SELECT -- would return True
REGEXP_LIKE(SPLIT_PART('AB.XYX.12.34.5670.89', '.', 1), '[A-Z0-9]{2}') AND
REGEXP_LIKE(SPLIT_PART('AB.XYX.12.34.5670.89', '.', 2), '[A-Z0-9]{3}') AND
REGEXP_LIKE(SPLIT_PART('AB.XYX.12.34.5670.89', '.', 3), '[A-Z0-9]{2}') AS abc
You need to add a .* at the end as the REGEXP_LIKE adds explicit ^ && $ to string:
The function implicitly anchors a pattern at both ends (i.e. '' automatically becomes '^$', and 'ABC' automatically becomes '^ABC$'). To match any string starting with ABC, the pattern would be 'ABC.*'.
select
column1 as str,
REGEXP_LIKE(str, '\\w{2}\\.\\w{3}\\.\\w{2}.*') as oracle_way
FROM VALUES
('AB.XYX.12.34.5670.89')
;
gives:
STR
ORACLE_WAY
AB.XYX.12.34.5670.89
TRUE
Or in the context of your question:
SELECT IFF(REGEXP_LIKE('AB.XYX.12.34.5670.89', '\\w{2}\\.\\w{3}\\.\\w{2}.*'), 'True', null) AS abc;
Your use of \w seems to suggest you don't need delimited strings to be strictly [A-Z0-9] since word characters allow underscore and period. If all bets were off and the only requirement was to have . at 3rd, 7th and 10th position, you could have used like this way.
select 'AB.XGH.12.34.5670.89' like '__.___.__.%' ;

Oracle query to find any special character in first position or end position of the field value

I have a table in Oracle database with special characters attached at first and last position in the field value. I want to eliminate those special characters while querying the table. I have used INSTR function but I had to apply for each and every special character using CASE expression.
Is there a way to eliminate any special characters that is attached only at first and last positions in one shot?
The query I am using as is below:
CASE WHEN
INSTR(emp_address,'"')=1 THEN REPLACE((emp_address,'"', '').
.
.
.
You can use regular expressions to replace the leading and trailing character of a string if they match the regular expression pattern. For example, if your definition of a "special character" is anything that is not an alpha-numeric character then you can use the regular expression:
^ the start-of-the-string then
[^[:alnum:]] any single character that does not match the POSIX alpha-numeric character group
| or
[^[:alnum:]] any single character that does not match the POSIX alpha-numeric character group then
$ the end-of-the-string.
Like this:
SELECT emp_address,
REGEXP_REPLACE(
emp_address,
'^[^[:alnum:]]|[^[:alnum:]]$'
) AS simplified_emp_address
FROM table_name
Which, for the sample data:
CREATE TABLE table_name (emp_address) AS
SELECT 'test' FROM DUAL UNION ALL
SELECT '"test2"' FROM DUAL UNION ALL
SELECT 'Not "this" one' FROM DUAL;
Outputs:
EMP_ADDRESS
SIMPLIFIED_EMP_ADDRESS
test
test
"test2"
test2
Not "this" one
Not "this" one
If you have a more complicated definition of a special character then change the regular expression appropriately.
db<>fiddle here

REGEXP_SUBSTR for portion of string

I would like to get:
82961_01B04WZXQQSUGJ4YMRRT2A7TRHK_MR_2_1of1
from the following expression
LASTNAME_FIRSTNAME_82961_01B04WZXQQSUGJ4YMRRT2A7TRHK_MR_2_1of1
Does someone know how I can get this using regexp_substr ?
EDIT
Basically I have a field which has 7 sets each separated by _ . The string I gave is just one example. I wanted to retrieve everything after the second _ . There is no fixed character length so I can not use a substr function. Hence I was using regexp_substr. I was able to get away by using a simplified version
Select FILE_NAME, ( (REGEXP_SUBSTR(FILE_NAME,'[^_]+_',1,3)) ||
(REGEXP_SUBSTR(FILE_NAME,'[^_]+_',1,4)) ||
(REGEXP_SUBSTR(FILE_NAME,'[^_]+_',1,5)) ||
(REGEXP_SUBSTR(FILE_NAME,'[^_]+_',1,6)) ||
(REGEXP_SUBSTR(FILE_NAME,'[^_]+',1,7)) ) as RegExp
from tbl
Here is some more data from the FILE_NAME field
LAST_FIRST_82961_01B04WZXQQSUGJ4YMRRT2A7TRHK_MR_2_1of1
SMITH_JOHN_82961_0130BPQX9QZN9G4P5RDTPA9HR4R_MR_1_1of1
LASTNAME_FIRSTNAME_99999_01V0MU4XUQK0Y24Y9RYTFA7W1CM_MR_3_1of1
To get everything after the second underscore, you do not need regular expressions, but can use something like the following:
select substr(FILE_NAME, instr(FILE_NAME, '_', 1, 2) +1 ) from tbl
The instr returns the position of the second occurrence of '_', starting by the first character; the substr simply gets everything starting from the position given by instr + 1
From your Requirement, you can just go ahead and use the simple SUBSTRfunction. Its faster, and it addresses the simple need to remove the String LASTNAME_FIRSTNAME.
select substr('LASTNAME_FIRSTNAME_82961_01B04WZXQQSUGJ4YMRRT2A7TRHK_MR_2_1of1', 20) data_string
from dual;
Output:
data_string
-----------------
82961_01B04WZXQQSUGJ4YMRRT2A7TRHK_MR_2_1of1
Unless you have another underlying logic you need to address?
Kindly clarify so i can edit the answer accordingly.

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;

Retrieving first X words from a string in Oracle Select

I need to select the first X words in a string, where x can be any number from 0-100. Is there an easy way to do this? I found the following example to select the first 2 words from a string:
select regexp_replace('Hello world this is a test', '(\w+ \w+).*$','\1') as first_two
from dual
How would I select the first X words from a string where X can be a number from 0-100?
Selecting the first four words:
select
regexp_replace(
'Hello world this is a test etc',
'(((\w+)\s){4}).*', -- Change 4 to wanted number of words here!
'\1'
)
from dual;
Edit
The above solution only works if the words are seperated by exactly one white space character. If the words are seperated by one or more white space characters, the \s must be extended to \s+:
select
regexp_replace(
'Hello world this is a test etc',
'(((\w+)\s+){4}).*', -- Change 4 to wanted number of words here!
'\1'
)
from dual;
This method takes the result of extracting the number of words you want, then reduces multiple spaces to one:
select trim(regexp_replace(regexp_substr('Hello world this is a test etc', '(([^ ]*)( |$)*){3}'), ' +', ' '))
from dual;
EDIT: This is getting ugly, but wrapped a TRIM() around it to get rid of the trailing space (the one after the last word selected).
this would do it, but it may be a bit inelegant, replace "2" with the number of words to find
select substr('this is a number of words',1,instr('this is a number of words',' ',1,2))
from dual
does assume words always end with a space

Resources