Oracle REGEXP_SUBSTR match words delimited by newline "\n" - oracle

I'm trying to split the string "SMITH\nALLEN\WARD\nJONES" in Oracle 10g by newline "\n" using a single SELECT query. Please help me to find the exact Regular Expression for this.
Expected Output:
1 SMITH
2 ALLEN\WARD
3 JONES
I have tried the expression "[^\n]+", but I got the following result which considered "\" as well. I want the expression to consider only "\n".
Query:
SELECT REGEXP_SUBSTR ('SMITH\nALLEN\WARD\nJONES',
'[^\n]+',
1,
LEVEL)
FROM DUAL
CONNECT BY REGEXP_SUBSTR ('SMITH\nALLEN\WARD\nJONES',
'[^\n]+',
1,
LEVEL) IS NOT NULL;
Result:
1 SMITH
2 ALLEN
3 WARD
4 JONES

Within the [] the characters are matched individually, and \n isn't seen a special character or even a run of characters anyway - it matches either of those characters individually; so even changing to [^\\n] wouldn't help.
You can use this form, which also returns empty elements:
select regexp_substr('SMITH\nALLEN\WARD\nJONES', '(.*?)(\\n|$)', 1, level, 'm', 1)
from dual
connect by level <= regexp_count('SMITH\nALLEN\WARD\nJONES', '\\n') + 1;
REGEXP_SUBSTR('SMITH\NAL
------------------------
SMITH
ALLEN\WARD
JONES

Related

FInd if the fifth position is a letter and not a number using ORACLE

How can I find if the fifth position is a letter and thus not a number using Oracle ?
My last try was using the following statement:
REGEXP_LIKE (table_column, '([abcdefghijklmnopqrstuvxyz])');
Perhaps you'd rather check whether 5th position contains a number (which means that it is not something else), i.e. do the opposite of what you're doing now.
Why? Because a "letter" isn't only ASCII; have a look at the 4th row in my example - it contains Croatian characters and these aren't between [a-z] (nor [A-Z]).
SQL> with test (col) as
2 (select 'abc_3def' from dual union all
3 select 'A435D887' from dual union all
4 select '!#$%&/()' from dual union all
5 select 'ASDĐŠŽĆČ' from dual
6 )
7 select col,
8 case when regexp_like(substr(col, 5, 1), '\d+') then 'number'
9 else 'not a number'
10 end result
11 from test;
COL RESULT
------------- ------------
abc_3def number
A435D887 not a number
!#$%&/() not a number
ASDĐŠŽĆČ not a number
SQL>
Anchor to the start of the string else you may get unexpected results. This works, but remove the caret (start of string anchor) and it returns 'TRUE'! Note it uses the case-insensitive flag of 'i'.
select 'TRUE'
from dual
where regexp_like('abcd4fg', '^.{4}[A-Z]', 'i');
Yet another way to do it:
regexp_like(table_column, '^....[[:alpha:]]')
Using the character class [[:alpha:]] will pick up all letters upper case, lower case, accented and etc. but will ignore numbers, punctuation and white space characters.
If what you care about is that the character is not a number, then use
not regexp_like(table_column, '^....[[:digit:]]')
or
not regexp_like(table_column, '^....\d')
Try:
REGEXP_LIKE (table_column, '^....[a-z]')
Or:
SUBSTR (table_column, 5, 1 ) BETWEEN 'a' AND 'z'

APEX validate alphabetic only allowed

In APEX 5.1 looking for validation script help to only allow alphabetic characters and a space or hyphen for a person's name. (i.e. no numbers or special characters other than a possible dash allowed).
I have a working validation for another field which allows alphanumeric but not special characters! Validation type is "Item does NOT contain any of the characters in Value". In the value field the following is placed... !##$%^&*()-_+=[]{};:'",<.>/?\|
I'd suggest you to use validation whose type is a function that returns Boolean and looks like this:
return regexp_like(:P1_ITEM_NAME, '^[A-Za-z -]+$');
What does it do?
^ is anchor to the beginning of the string
A-Z accepts capital letters
a-z accepts lowercase letters
space is ... well, a space
- is ... well, a hyphen
+ - repeat those characters many times
$ is anchor to the end of the string
For example:
SQL> with test (item) as
2 (select 'aBCd' from dual union -- ok
3 select 'little foot' from dual union -- ok
4 select 'reb-ecca' from dual union -- ok
5 select 'lit123foot' from dual union -- wrong
6 select 'abc$3' from dual union -- wrong
7 select 'xy.)z' from dual union -- wrong
8 select '123-234' from dual -- wrong
9 )
10 select item
11 from test
12 where regexp_like(item, '^[A-Za-z -]+$');
ITEM
-----------
aBCd
little foot
reb-ecca
SQL>

oracle regexp_replace to remove commas between Quote

Please can anybody help me out please. Have been trying for days to get a regexp_replace to remove commas between quotes irrespective of the commas position.
Example
cold, gold, "Block 12C, Jones Avenue, Broad Street, London", car
Expected Answer
cold, gold, "Block 12C Jones Avenue Broad Street London", car
thanks in advance
You could extract the contents within double quotes(REGEXP_SUBSTR), replace the commas, and stuff it back to the old string using replace.
select REPLACE (whole_str,quoted_str,REPLACE (quoted_str,',')) FROM
(
select
whole_str,
REGEXP_SUBSTR( whole_str, '^[^"]*("[^"]+")',1,1,NULL,1) quoted_str
FROM yourtable
);
DEMO
Note that this could also be done using INSTR,SUBSTR which could be more efficient, but hard to read.
You can use regexp_replace to get the desired output :
with t( id , val ) as(
select 1,'cold, gold, "Block 12C, Jones Avenue, Broad Street, London", car' from dual union
select 2,'"Block 12C, Jones Avenue, Broad Street, London", car, cold, gold' from dual )
select id, val value
from t
model dimension by( id ) measures( val )
rules iterate(100)( val[any] = regexp_replace(val[cv()],',(([^"]*"){2})*([^"]*"[^"]*)$',' \1\3') );
d E m O
I doubt that there is a single regular expression function that will achieve the desired result. The "obvious" line of attack is to chop the input string into pieces and delete commas from each double-quoted substring as needed. (Unless each string has at most ONE double-quoted substring, in which case the problem has easier answers - but judging from the sample input string, it is possible that the same needs to be done for input strings with an arbitrary number of double-quoted substrings.)
Here is a solution using a recursive WITH clause - so it requires Oracle 11.2 or higher. (For earlier versions, a solution with a CONNECT BY hierarchical query can be used instead.) I wrote it with regular expressions, as requested; if speed becomes an issue, it can be re-written with standard INSTR, SUBSTR and REPLACE functions.
In the first factored subquery (subquery in the WITH clause) I created a few more inputs, to test whether the solution returns the correct result in different situations.
with
inputs ( str ) as (
select 'cold, gold, "Block 12C, Jones Ave., London", car' from dual union all
select '"One, two, three","Four, five six,",' from dual union all
select 'No, double-quotes, in this, string' from dual union all
select 'No commas in "double quotes" here' from dual
),
r ( str, init, quoted, fin ) as (
select str, null, null, str
from inputs
union all
select str,
init || replace(quoted, ',') || regexp_substr(fin, '[^"]*'),
regexp_substr(fin, '"[^"]*"'),
regexp_substr(fin, '([^"]*"){2}(.*)', 1, 1, null, 2)
from r
where quoted is not null or fin is not null
)
select str, init as new_str
from r
where quoted is null and fin is null
;
STR NEW_STR
--------------------------------------------- -------------------------------------------
No, double-quotes, in this, string No, double-quotes, in this, string
cold, gold, "Block 12C, Jay Ave, London", car cold, gold, "Block 12C Jay Ave London", car
No commas in "double quotes" here No commas in "double quotes" here
"One, two, three","Four, five six,", "One two three","Four five six",

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;

Oracle : how to display second or third letter in each word of sentence as CAPITAL letter in Oracle

how to display second or third letter in each word of sentence as CAPITAL letter in Oracle.
Testdata:
hyderabad
Output:
hYderabad or hyDerabad
To make 2nd character to upper case
select SUBSTR(test_data,1,1)||INITCAP(SUBSTR(test_data,2)) from test_table;
To make the 3rd character to upper case, increment the last argument of both SUBSTR with 1.
Example
select SUBSTR(test_data,1,2)||INITCAP(SUBSTR(test_data,3)) from test_table;
Use this for 2nd digit as upper case.
WITH TBL(TESTDATA) AS
( SELECT 'hyderabad' FROM DUAL UNION
SELECT 'pune' FROM DUAL UNION
SELECT '223jjjj22' FROM DUAL
)
SELECT substr(testdata,1,1)||upper(substr(testdata,2,1))
||substr(testdata,3,length(testdata)-2)
as output
FROM TBL
Output
223jjjj22
hYderabad
pUne
Here I fetched first character,upper case of second character and rest of characters separately. Then I concatenated them.
You can use similar approach for 3rd character if you want.

Resources