SELECT REGEXP_SUBSTR('one,two,three',',[^,]+') AS reg_result FROM DUAL;
REG_RESULT
,two
SELECT REGEXP_SUBSTR('eight,nineteen,five',',[^,]+') AS reg_result FROM DUAL;
REG_RESULT
,nineteen
I have to remove the " , " from the result. Also I want the last string
as the output. i.e. three from 'one,two,three' & five from 'eight,nineteen,five'.
How can I do it??
If want to just get the last word without checking if your string meets particular pattern:
SQL> with t1 as(
2 select 'one,two,three' as str from dual
3 )
4 select regexp_substr(str, '([[:alpha:]]+)$') last_word
5 from t1
6 ;
LAST_WORD
---------
three
Response to the comment
how to get string two from the first one & nineteen from the second??
Fourth parameter of the regexp_substr function is the occurrence of a pattern. So to get the second word in the string we can use regexp_substr(str, '[^,]+', 1, 2)
SQL> with t1 as(
2 select 'one,two,three' as str from dual
3 )
4 select regexp_substr(str, '[^,]+', 1, 2) as Second_Word
5 from t1;
Second_Word
---------
two
If there is a need to extract every word from your strings:
-- sample of data from your question
SQL> with t1 as(
2 select 'one,two,three' as str from dual union all
3 select 'eight,nineteen,five' from dual
4 ), -- occurrences of the pattern
5 occurrence as(
6 select level as ps
7 from ( select max(regexp_count(str, '[^,]+')) mx
8 from t1
9 ) s
10 connect by level <= s.mx
11 ) -- the query
12 select str
13 , regexp_substr(str, '[^,]+', 1, o.ps) word
14 , o.ps as word_num
15 from t1 t
16 cross join occurrence o
17 order by str
18 ;
STR WORD WORD_NUM
------------------- ----------- ----------
eight,nineteen,five eight 1
eight,nineteen,five nineteen 2
eight,nineteen,five five 3
one,two,three three 3
one,two,three one 1
one,two,three two 2
6 rows selected
SELECT REGEXP_SUBSTR(REGEXP_SUBSTR('one,two,three',',[^,]+$'),'[^,]+') AS reg_result FROM DUAL;
I'm not certain if Oracle has lookbehinds, but you can try this as well:
SELECT REGEXP_SUBSTR('one,two,three','(?<=,)[^,]+$') AS reg_result FROM DUAL;
Related
Could you please tell me the expression regexp_like to check if a string has the format which begins with one or two letters max followed by numbers. For example, like 'A25', 'AB567'.
Thanks
How about
SQL> with test (col) as
2 (select 'A25' from dual union all
3 select 'AB567' from dual union all
4 select 'A12A532A' from dual union all
5 select 'ABC123' from dual union all
6 select '12XYZ34' from dual
7 )
8 select col,
9 case when regexp_like(col, '^[[:alpha:]]{1,2}[[:digit:]]+$') then 'OK'
10 else 'Wrong'
11 end result
12 from test;
COL RESULT
---------- ----------
A25 OK
AB567 OK
A12A532A Wrong
ABC123 Wrong
12XYZ34 Wrong
SQL>
The regular expression would be ^[A-Z]{1,2}[0-9]+$.
Working demo on db<>fiddle here
This match a string that contain only numbers and letters, that start with a letter, when there is never more than 2 letters in a row.
^(([A-Za-z]){1,2}([0-9])+)*\2{0,2}$
I am trying to find the pattern using oracle sql developer. Include numbers that are "x0000"," 0000",".0000"
AND REGEXP_INSTR(string=>FTP.TEXT, pattern=>'[x]\d\d\d\d\s', match_parameter=>'i')
Use
where REGEXP_LIKE(str,'[x.[:space:]]\d{4}','i')
The [x.[:space:]]\d{4} expression matches x, . or any whitespace, then any four digit characters.
You can use REGEXP_LIKE as follows:
SQL> --sample data
SQL> with your_data(id,str) as
2 (select 1, 'x0000' from dual union all
3 select 2, '.0000' from dual union all
4 select 3, ' 0000'from dual union all
5 select 4, '0000' from dual) -- this should not be in the result
6 -- your query starts from here
7 select * from your_data
8 where REGEXP_like(str,'[x| |\.][0-9]{4}','i');
ID STR
---------- -----
1 x0000
2 .0000
3 0000
SQL>
I want to get the time pattern along with AM or PM from the given string Aaaaa_gggg_ne_A030_66788_Abcd_Oct_24_0329PM.csv
I tried the following:
Select regexp_substr(filename,'\d{4}',1,3)
From
(Select 'Aaaaa_gggg_ne_A030_66788_Abcd_Oct_24_0329PM.csv' filename from dual);
which only gives me the last number, e.g. 0329, but I need 0329PM.
Using this form of REGEXP_SUBSTR() will get what you need in one call. It returns the first group, which is the set of characters after the last underscore and before the literal period of 1 or more numbers followed by an A or P then an M.
with tbl(filename) as (
Select 'Aaaaa_gggg_ne_A030_66788_Abcd_Oct_24_0329PM.csv'
from dual
)
select regexp_substr(filename, '_(\d+[AP]M)\.', 1, 1, NULL, 1)
From tbl;
Actually, to tighten up the match you could make it case-insensitive and add the extension:
select regexp_substr(filename, '_(\d+[AP]M)\.csv', 1, 1, 'i', 1)
From tbl;
Note if a match is not found NULL will be returned.
Nested substr is one option (if data always looks like this; you didn't say it doesn't):
SQL> with test (col) as
2 (select 'Aaaaa_gggg_ne_A030_66788_Abcd_Oct_24_0329PM.csv' from dual)
3 select substr(substr(col, -10), 1, 6) result from test
4 /
RESULT
------
0329PM
SQL>
the inner substr returns the last 10 characters (0329PM.csv)
the outer substr returns the first 6 characters out of it (0329PM)
Or, using regular expressions:
SQL> with test (col) as
2 (select 'Aaaaa_gggg_ne_A030_66788_Abcd_Oct_24_0329PM.csv' from dual)
3 select regexp_substr(translate(col, '_.', ' '), '\S+',
4 1,
5 regexp_count(translate(col, '_.', ' '), '\S+') - 1
6 ) result
7 from test;
RESULT
------
0329PM
SQL>
line #3: translate replaces underlines and dots with a space
line #4: start from the beginning
line #5: return substring which is one before the last one
Is there any way to find consecutive repetitive characters like 1414, 200200 in a varchar column of an oracle table.
how can we achieve it with regexp ?
Im failing to achieve it with regexp
im my example i can get a consecutive repetition of a number but not a pattern
select regexp_substr('4120066' ,'([[:alnum:]])\1', 7,1,'i') from dual; -- getting output as expected
select regexp_substr('6360360' ,'([[:alnum:]])\1', 7,1,'i') from dual; -- i want to select this also as i have 360 followed by 360
You should be able to use something like this:
[...] WHERE REGEXP_LIKE(field, '(\d+?)\1')
If you're looking for any repetition of characters, or:
[...] WHERE REGEXP_LIKE(field, '^(\d+?)\1$')
If you want to check the whole string in the field.
\d+? will match digits.
( ... ) will store those digits.
\1 refers to the captured digits.
Note: Change to \d to . if you are not checking digits only.
Try this :
SQL> WITH t AS
2 (SELECT '1414,200200,11,12,33,33,1234,1234' test_string
3 FROM DUAL)
4 SELECT LTRIM (SYS_CONNECT_BY_PATH (test_string, ','), ',') names
5 FROM (SELECT ROW_NUMBER () OVER (ORDER BY test_string) rno, test_string
6 FROM (SELECT DISTINCT REGEXP_SUBSTR (test_string,
7 '[^,]+',
8 1,
9 LEVEL
10 ) test_string
11 FROM t
12 CONNECT BY LEVEL <=
13 LENGTH (test_string)
14 - LENGTH (REPLACE (test_string,
15 ',',
16 NULL
17 )
18 )
19 + 1))
20 WHERE CONNECT_BY_ISLEAF = 1 AND ROWNUM = 1
21 CONNECT BY rno = PRIOR rno + 1;
NAMES
--------------------------------------------------------------------------------
11,12,1234,1414,200200,33
None of the delimited string repeat !
If I used the following expression, the result should be 1.
regexp_instr('500 Oracle Parkway, Redwood Shores, CA','[[:digit:]]')
Is there a way to make this look for the last number in the string? If I were to look for the last number in the above example, it should return 3.
If you were using 11g, you could use regexp_count to determine the number of times that a pattern exists in the string and feed that into the regexp_instr
regexp_instr( str,
'[[:digit:]]',
1,
regexp_count( str, '[[:digit:]]')
)
Since you're on 10g, however, the simplest option is probably to reverse the string and subtract the position that is found from the length of the string
length(str) - regexp_instr(reverse(str),'[[:digit:]]') + 1
Both approaches should work in 11g
SQL> ed
Wrote file afiedt.buf
1 with x as (
2 select '500 Oracle Parkway, Redwood Shores, CA' str
3 from dual
4 )
5 select length(str) - regexp_instr(reverse(str),'[[:digit:]]') + 1,
6 regexp_instr( str,
7 '[[:digit:]]',
8 1,
9 regexp_count( str, '[[:digit:]]')
10 )
11* from x
SQL> /
LENGTH(STR)-REGEXP_INSTR(REVERSE(STR),'[[:DIGIT:]]')+1
------------------------------------------------------
REGEXP_INSTR(STR,'[[:DIGIT:]]',1,REGEXP_COUNT(STR,'[[:DIGIT:]]'))
-----------------------------------------------------------------
3
3
Another solution with less effort is
SELECT regexp_instr('500 Oracle Parkway, Redwood Shores, CA','[^[:digit:]]*$')-1
FROM dual;
this can be read as.. find the non-digits at the end of the string. and subtract 1. which will give the position of the last digit in the string..
REGEXP_INSTR('500ORACLEPARKWAY,REDWOODSHORES,CA','[^[:DIGIT:]]*$')-1
--------------------------------------------------------------------
3
which i think is what you want.
(tested on 11g)