removing character after 3 different specific characters - oracle

I have a problem to get a result as example below using oracle. I have a lot of different data in a field A, and need to do a few step (as below) to become a result in field B.
example:
LM2963NAMBLK-P/NOPB/SA and the result: LM2963NAM
remove all characters after '/'
remove character '-P'
remove character 'BLK'

The below should work:
select A,
regexp_replace(
regexp_replace(A, '-P|/.*', ''),
'^(.*)BLK$', '\1'
) B
--remainder of query
The nested regexp_replace will replace -P or / followed by 0 or more occurrences of any characters with the empty string, leaving you with your desired output plus a possible BLK at the end. The | represents "or." I'm not logged in to oracle at the moment, but the - and / shouldn't need to be escaped as / is not a special character in Oracle regex and - is only a special character inside of [ ]. The outside regexp_replace will replace BLK at the end with the empty string if it is there, or just return your string if it is not there.

Well, this is one way...
select substr( substr( substr( 'LM2963NAMBLK-P/NOPB',1, slash_pos-1 ), 1, dash_p_pos-1 ), 1, blk_pos-1 )
from
(
select 'LM2963NAMBLK-P/NOPB'
, instr( 'LM2963NAMBLK-P/NOPB', '/' ) slash_pos
, instr( 'LM2963NAMBLK-P/NOPB', '-P' ) dash_p_pos
, instr( 'LM2963NAMBLK-P/NOPB', 'BLK' ) blk_pos
from dual
);
SUBSTR(SU
---------
LM2963NAM

Related

Need to extract text with REGEXP_SUBSTR - cannot find the right combination

Here is an example of my text- I am trying to get TEXTPART3 AS THE ANSWER:
TEXTPART1 : TEXTPART2: TEXTPART3 - TEXTPART4
I used TRIM(LEADING ':' FROM REGEXP_SUBSTR('textstatementhere', ':.+?-')) - but it is not accounting for the two ":" and the "-" in the text statement I get ' TEXTPART2: TEXTPART3 -'
Can anyone help?
Thanks in advance!
The problem has a more efficient solution using only standard string functions:
with
sample_input (str) as (
select 'TEXTPART1 : TEXTPART2: TEXTPART3 - TEXTPART4' from dual
)
select substr(str, pos, instr(str, '-', pos) - pos - 1) as text_part_3
from (select str, instr(str, ':', 1, 2) + 2 as pos from sample_input)
;
TEXT_PART_3
-----------
TEXTPART3
Leverage the REGEXP_SUBSTR Function to Do All of Your Work
Use a subexpression, (\w), and reference it:
WITH exmple AS (
SELECT
'TEXTPART1 : TEXTPART2: TEXTPART3 - TEXTPART4' txt
FROM
dual
)
SELECT
txt,
regexp_substr(txt, ': (\w*) -', 1, 1, NULL,
1)
FROM
exmple;
I see that you used ., in lieu of \w. Because you chose the meta-character,. (which represents all characters except new line (though that can be included if "n" is set as a pattern matching modifier)), the second colon is thrown in to the matching set.
What does TEXTPART3 include?
Perhaps the meta-character, \w, (which stands for alphanumeric or underscore (_) character), is not what you need.
You could replace it with a non-matching character list to avoid the problems with .:
[^:].
This approach would look like this:
REGEXP_SUBSTR(txt, ': ([^:]*) -',1,1,NULL,1)
Lastly, with the quantiifier associated with this subexpression, I used * which means zero or more matches. I assumed that there would be instances where there could be zero matches for this TEXTPART3. If this is not the case, we can use +.

How to apply regular expression on the below given string

i have a string 'MCDONALD_YYYYMMDD.TXT' i need to use regular expressions and append the '**' after the letter 'D' in the string given . (i.e In the string at postion 9 i need to append '*' based on a column value 'star_len'
if the star_len = 2 the o/p = ''MCDONALD??_YYYYMMDD.TXT'
if the star_len = 1 the o/p = ''MCDONALD?_YYYYMMDD.TXT'
with
inputs ( filename, position, symbol, len ) as (
select 'MCDONALD_20170812.TXT', 9, '*', 2 from dual
)
-- End of simulated inputs (for testing purposes only, not part of the solution).
-- SQL query begins BELOW THIS LINE.
select substr(filename, 1, position - 1) || rpad(symbol, len, symbol)
|| substr(filename, position) as new_str
from inputs
;
NEW_STR
-----------------------
MCDONALD**_20170812.TXT
select regexp_replace('MCDONALD_YYYYMMDD.TXT','MCDONALD','MCDONALD' ||
decode(star_len,1,'*',2,'**'))
from dual
This is how you could do it. I don't think you need it as a regular expression though if it is always going to be "MCDONALD".
EDIT: If you need to be providing the position in the string as well, I think a regular old substring should work.
select substr('MCDONALD_YYYYMMDD.TXT',1,position-1) ||
decode(star_len,1,'*',2,'**') || substr('MCDONALD_YYYYMMDD.TXT',position)
from dual
Where position and star_len are both columns in some table you provide(instead of dual).
EDIT2: Just to be more clear, here is another example using a with clause so that it runs without adding a table in.
with testing as
(select 'MCDONALD_YYYYMMDD.TXT' filename,
9 positionnum,
2 star_len
from dual)
select substr(filename,1,positionnum-1) ||
decode(star_len,1,'*',2,'**') ||
substr(filename,positionnum)
from testing
For the fun of it, here's a regex_replace solution. I went with a star since that what your variable was called even though your example used a question mark. The regex captures the filename string in 2 parts, the first being from the start up to 1 character before the position value, the second the rest of the string. The replace puts the captured parts back together with the stars in between.
with tbl(filename, position, star_len ) as (
select 'MCDONALD_20170812.TXT', 9, 2 from dual
)
select regexp_replace(filename,
'^(.{'||(position-1)||'})(.*)$', '\1'||rpad('*', star_len, '*')||'\2') as fixed
from tbl;

How to get the second last word in a string?

I have a string like below, and I need to get 10472314 in it. It is the last word but one in this case. Can you let me know how to get it in PL/SQL block? Any string function?
processed "SCOTT"."PRINCE05" 10472314 rows
The set of digits before the word 'rows' at the end of the string:
regexp_replace(text, '^(.+ )([0-9]+)( rows)$', '\2')
The third word:
regexp_substr(text, '\S+', 1, 3)
The second last word (the nth word where n = the number of words -1):
regexp_substr(text, '\S+', 1, regexp_count(text,'\S+') -1)
If you are processing a significant number of rows then the regex functions can be slow. The trade-off you have to make is between the expressiveness of regular expressions and the performance of plain substr and instr. Personally I prefer regexes unless there is a clear performance issue.
This gets you the last TWO words in a string and then shows you the first word of those two words which will always be the second-last word:
SUBSTRING_INDEX(SUBSTRING_INDEX(, " ", -2), ' ', 1)
If we use a '-1' magic option in INSTR then we can search the string in reverse order. By doing that, I believe we can find the last word but one like below.
It looks dirty but it just works for me.
SELECT SUBSTR( name, INSTR( name, ' ', -1 , 2 ) + 1 , INSTR( name, ' ', -1 , 1 ) - INSTR( name, ' ', -1 , 2 ) )
FROM prince_test;
INSTR( name, ' ', -1 , 2 ) + 1 ==> the second occurrence of SPACE
INSTR( name, ' ', -1 , 1 ) - INSTR( name, ' ', -1 , 2 ) ==> position gap between the first occurrence and the second.

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;

Oracle insert character into a string

I have this table of rows
RowA
______
ABC123
DEF432
WER677
JKL342
how can I add a '_' in between the record using oracle to this?
Assuming to add on the last 4 character.
RowA
______
ABC_123
DEF_432
WER_677
JKL_342
You would try something like:
Update Table_name set table_column = substr(table_column, 1, 3) || '_' || substr(table_column, 4);
The SUBSTR functions allows you to extract a substring from a string.
The syntax for the SUBSTR function is:
SUBSTR( string, start_position, [ length ] )
string is the source string.
start_position is the position for extraction. The first position in the string is always 1.
length is optional. It is the number of characters to extract. If this parameter is omitted, the SUBSTR function will return the entire string.
Another approach, using regexp_replace() regular expression function:
select regexp_replace(RowA, '^([[:alpha:]]{3})', '\1_') as res
from your_table
Result:
RES
----------
ABC_123
DEF_432
WER_677
JKL_342
SQLFiddle Demo

Resources