I have sample mail-id like below:
raju.das#gmail.com
javed.khan#gmail.com
Amit.kumar.bera#yahoo.com
So, I need the output like below:
das Gmail
Khan gmail
bera yahoo
Using regexp am able to do it, but It's not giving correct output when mail id is coming with middle name. Can anyone please help me on it.
You can use the simple string functions INSTR and SUBSTR (which are much faster than regular expressions):
SELECT SUBSTR(local_part, INSTR(local_part, '.', -1) + 1) AS last_name,
SUBSTR(domain, 1, INSTR(domain, '.') - 1) AS domain
FROM (
SELECT SUBSTR(email, 1, INSTR(email, '#', -1) - 1) AS local_part,
SUBSTR(email, INSTR(email, '#', -1) + 1) AS domain
FROM table_name
)
Which, for the sample data:
CREATE TABLE table_name(email) AS
SELECT 'raju.das#example.com' FROM DUAL UNION ALL
SELECT 'javed.khan#example.com' FROM DUAL UNION ALL
SELECT 'Amit.kumar.bera#example.com' FROM DUAL;
Outputs:
LAST_NAME
DOMAIN
das
example
khan
example
bera
example
If you did want to use regular expression (which will be slower) then:
SELECT REGEXP_SUBSTR(email, '([^.]+)#([^.]+)', 1, 1, NULL, 1) AS last_name,
REGEXP_SUBSTR(email, '([^.]+)#([^.]+)', 1, 1, NULL, 2) AS domain
FROM table_name;
Gives the same output.
fiddle
Related
I need to break out the name field to show last name and first initial in separate fields.
So far, I can break out the LastName, FirstName, but is there a way I can only select the first name initial?
regexp_substr(name, '[^,]+', 1, 1) as LastName,
regexp_substr(name, '[^,]+', 1, 2) as FirstName
I'm confused didn't see "oracle" tag. So these code snippets will only work with SQL Server:
You can do this by using standard string functions.
DECLARE #name VARCHAR(100);
SELECT #name = 'Tom Sheldon'
-- you can use this instead of regular expressions
SELECT RIGHT(#name, CHARINDEX(' ', #name)+3) + ' ' + LEFT(#name, 1) + '.' AS name
Returns:
name
Sheldon T.
and
DECLARE #name VARCHAR(100);
SELECT #name = 'Tom Sheldon'
-- you can use this instead of regular expressions
SELECT
RIGHT(#name, CHARINDEX(' ', #name)+3) AS LastName,
LEFT(#name, 1) AS FirstName
Returns:
LastName
FirstName
Sheldon
T
you can use SUBSTR with the resuklt of the regexp_substr
with rws as (
select 'lastname,firstname' str from dual
)
SELECT regexp_substr(str, '[^,]+', 1, 1) as LastName,
SUBSTR(regexp_substr(str, '[^,]+', 1, 2),1,1) as FirstNameinitial
from rws
LASTNAME | FIRSTNAMEINITIAL
:------- | :---------------
lastname | f
db<>fiddle here
Hah!
This might be inelegant, but it worked:
substr ( (regexp_substr(name, '[^,]+', 1, 2)),2,1 ) as FirstName
I started the substring at 2, b/c there was a space between the comma and the first name. I now have two columns: LastName, FirstInit
Assuming that the separator is a comma, and using old-school INSTR() and SUBSTR(), this version will allow for the possibility that there may be zero or more spaces following the comma:
WITH nrow AS (
SELECT 'Lastname, Firstname' AS pers_name
FROM dual
)
SELECT SUBSTR (pers_name, 1, INSTR (pers_name, ',') - 1) AS last_name,
SUBSTR (LTRIM (SUBSTR (pers_name, INSTR (pers_name, ',') + 1)), 1, 1) AS first_init
FROM nrow
/
In the table code_subject there is a row with a following format string1#string2#integer#string3. How to extract a number (integer) from it?
IS IT LIKE THAT?:
SELECT REGEXP_SUBSTR('integer') "REGEXPR_SUBSTR" FROM code_subject
One way could be using regexp_replace:
select regexp_replace('stringA#stringB#1234#stringC', '[^0-9]', '')
from dual;
Another possibility is:
select substr('string1#string2#1234#string3', instr('string1#string2#1234#string3', '#', 1, 2) + 1,
instr('string1#string2#1234#string3', '#', 1, 3) - instr('string1#string2#1234#string3', '#', 1, 2) - 1)
from dual;
I try to get first name, last name, provider from an email address "ben.ghol#gmail.com" but it doesn't work.
Table emailtable.
My code here:
select
SUBSTR(email,1, INSTR(email,'.')-1) as firstname,
SUBSTR(email,INSTR(email,'.')+1, INSTR(email,'#')-1) as lastname,
SUBSTR(email,INSTR(email,'#')+1,INSTR(email,'.')-1) as "provider"
from emailtable;
The third argument for SUBSTR is the length of the substring (and not the position of the end character).
You can use a nested sub-query to find the position of the separators and then use those values in SUBSTR in the outer query:
SELECT SUBSTR(email, 1, name_separator - 1) AS first_name,
SUBSTR(email, name_separator + 1, at_separator - name_separator - 1)
AS last_name,
SUBSTR(email, at_separator + 1, domain_separator - at_separator - 1)
AS domain
FROM (
SELECT email,
INSTR(email, '.') AS name_separator,
INSTR(email, '#') AS at_separator,
INSTR(email, '.', INSTR(email, '#')) AS domain_separator
FROM emailtable
)
Which, for the sample data:
CREATE TABLE emailtable ( email ) AS
SELECT 'ben.ghol#gmail.com' FROM DUAL;
Outputs:
FIRST_NAME
LAST_NAME
DOMAIN
ben
ghol
gmail
db<>fiddle here
You can use regexp_substr():
select regexp_substr(email, '^[^.]+') as firstname,
regexp_substr(email, '[^.#]+', 1, 2) as lastname,
regexp_+substr(email, '[^#]+$') as provider
from (select 'ben.ghol#gmail.com' as email from dual) x;
Here is a db<>fiddle.
SUBSTR takes 3 parameters: input string, start position and length of substring.
You appear to be using end position as the 3rd parameter.
You can get the length to use as the 3rd parameter by doing (end position - start position + 1)
I have a string with under score and some characters. I need to apply substring and get values to the left excluding underscore. So I applied below formula and its working correctly for those strings which have underscore (_). But for strings without (_) it is bringing NULL. Any suggestions how this can be handled in the substring itself.
Ex: ABC_BASL ---> Works correctly; ABC ---> gives null
My formula as below -
select SUBSTR('ABC_BAS',1,INSTR('ABC_BAS','_')-1) from dual;
ABC
select SUBSTR('ABC',1,INSTR('ABC','_')-1) from dual;
(NULL)
You could use a CASE expression to first check for an underscore:
WITH yourTable AS (
SELECT 'ABC_BAS' AS col FROM dual UNION ALL
SELECT 'ABC' FROM dual
)
SELECT
CASE WHEN col LIKE '%\_%' ESCAPE '\'
THEN SUBSTR(col, 1, INSTR(col, '_') - 1)
ELSE col END AS col_out
FROM yourTable;
Use regular expression matching:
SELECT REGEXP_SUBSTR('ABC_BAS', '(.*)([_]|$)?', 1, 1, NULL, 1) FROM DUAL;
returns 'ABC', and
SELECT REGEXP_SUBSTR('ABC', '(.*)([_]|$)?', 1, 1, NULL, 1) FROM DUAL;
also returns 'ABC'.
db<>fiddle here
EDIT
The above gives correct results, but I missed the easiest possible regular expression to do the job:
SELECT REGEXP_SUBSTR('ABC_BAS', '[^_]*') FROM DUAL;
returns 'ABC', as does
SELECT REGEXP_SUBSTR('ABC', '[^_]*') FROM DUAL;
db<>fiddle here
Yet another approach is to use the DECODE in the length parameter of the substr as follows:
substr(str,
1,
decode(instr(str,'_'), 0, lenght(str), instr(str,'_') - 1)
)
You seem to want everything up to the first '_'. If so, one method usesregexp_replace():
select regexp_replace(str, '(^[^_]+)_.*$', '\1')
from (select 'ABC' as str from dual union all
select 'ABC_BAS' from dual
) s
A simpler method is:
select regexp_substr(str, '^[^_]+')
from (select 'ABC' as str from dual union all
select 'ABC_BAS' from dual
) s
Here is a db<>fiddle.
I'd use
regexp_replace(text,'_.*')
or if performance was a concern,
substr(text, 1, instr(text||'_', '_') -1)
For example,
with demo(text) as
( select column_value
from table(sys.dbms_debug_vc2coll('ABC', 'ABC_DEF', 'ABC_DEF_GHI')) )
select text
, regexp_replace(text,'_.*')
, substr(text, 1, instr(text||'_', '_') -1)
from demo;
TEXT REGEXP_REPLACE(TEXT,'_.*') SUBSTR(TEXT,1,INSTR(TEXT||'_','_')-1)
------------ --------------------------- -------------------------------------
ABC ABC ABC
ABC_DEF ABC ABC
ABC_DEF_GHI ABC ABC
Ok i think i got it. Add nvl to the substring and insert the condition as below -
select nvl(substr('ABC',1,instr('F4001Z','_')-1),'ABC') from dual;
I have some filename like 'abc-type-bank-20200112-1578796204118.csv'
i want to get the value 'bank' from above which is 3rd value if I cut the string by '-'.
If my filename is like abc-type-XYZ-20200112-1578796204118.csv, I should get 'XYZ' from 3rd position.
I was trying to get by below code, but it giving wrong value.
select substr(v_FILE_NAME,1,instr(v_FILE_NAME, '-') + 3) as name from (
select 'abc-type-bank-20200112-1578796204118.csv' as v_FILE_NAME from dual);
To use SUBSTR and INSTR to extract your desired substring you'd do something like
WITH cteData AS (SELECT 'abc-type-bank-20200112-1578796204118.csv' AS FILENAME FROM DUAL),
ctePos AS (SELECT FILENAME,
INSTR(FILENAME, '-', 1, 2) AS DASH_2_POS,
INSTR(FILENAME, '-', 1, 3) AS DASH_3_POS
FROM cteData)
SELECT SUBSTR(FILENAME, DASH_2_POS + 1, DASH_3_POS - DASH_2_POS - 1) AS SUBSTR_3
FROM ctePos
The above will extract the substring 'bank' from the sample data.
db<>fiddle here
The use of dual suggests Oracle. In that database you can use regexp_substr():
select regexp_substr(filename, '[^-]+', 1, 3)
from (select 'abc-type-XYZ-20200112-1578796204118.csv' as filename from dual) x;