Get the FIrst character from the Firstname if more than one firstname is present in oracle - sql

I have a requirement where the persons can have more than one first name and i need to convert the name into first characters from the 2 or more names with capital letters.
Examples:
Srinivas Kalyan ,Sai Kishore
if the above is one having 4 first names then i need to display as below
S K S K
The comma is also be replaced and take all the first characters
2. Srinivas-Kalyan Sai Kishore
For the above name the value should be as
S S K
since Srinivas-Kalyan is considered as one name
Also the name can be in small letters
srinivas kalyan sai kishore
For this
S K S K
This has to be in oracle
Tried the below regex_replace which is working fine in sql developer but in the application it is changing into space
replace(trim(regexp_replace(to_char(regexp_replace(initcap(regexp_replace(regexp_replace
(FIRST_NAME, '[0-9]', ''), '( *[[:punct:]])', '')), '([[:lower:]]| )')), '(.)', '\1 ')),',',null)

The missing letter in your output is caused by this regex for character removal:
( *[[:punct:]])
This will turn Kalyan ,Sai into KalyanSai, which will be treated as one word by the rest of the process, and so you will not have the S of Sai in your output.
I would suggest this shorter expression:
trim(upper(regexp_replace(
regexp_replace(first_name, '([[:alpha:]])(-|[[:alpha:]])+', '\1'),
'.*?([[:alpha:]]|$)', ' \1'
)))
Explanation
([[:alpha:]])(-|[[:alpha:]])+ -> \1
This replaces any sequence of letters (or hyphen) with the first of those. So it reduces words to their initial letter.
.*?([[:alpha:]]|$) -> (space)\1
This replaces anything that precedes the next letter, with a space. As no letter will be skipped (because .*? is non-greedy) this effectively replaces all non-letter sequences with a space. To also replace the non-letters at the very end (which do not precede a letter), the special case $ (end-of-string) is added as alternative.
After these two steps there just remains to:
Upper case everything
Remove blanks at the start and end of the result with trim
I find the advantage of this method is that it does not use any other class than [[:alpha]]. Digits, punctuation, lowercase -- or whatever else -- does not need to be identified explicitly, as it is just the negation of [[:alpha]]. The only exception that has to be made, is for the hyphen.
As some names might include some other non-letters, like a quote, you might want to add such characters as well in the first regular expression.

Related

Remove space between number and character - PostgreSQL/REGEXP_REPLACE

I have a table with medication_product_amount column where there are spaces between numbers and characteres like below:
medication_product_amount
1 UN DE 50 ML
20 UN
1 UN DE 600 G
What I want is to remove the single space ONLY between numbers and characters, something like this:
new_medication_product_amount
1UN DE 50ML
20UN
1UN DE 600G
To do this, I am looking for a regular expression to use in the function REGEXP_REPLACE. I tried using the pattern below, indicating to replace the single space after the numbers, but the output remained the same as the input:
select REGEXP_REPLACE(medication_product_amount, '(^[0-9])( )', '\1') as new_medication_product_amount
from medications
Can anyone help me come up with the right way to do this? Thanks!
Your regex is a little off. First what yours does. '(^[0-9])( )', '\1')
(^[0-9]) Start Capture (field 1) at the beginning of the string for 1 digit
followed by Start Capture (field 2) for 1 space.
Replace the string by field1.
The problems and correction:
What you want to capture does not necessary the first character of the string. So eliminate the anchor ^.
What you want to capture may be more that 1 digit in length. So replace [0-9] by [0-9]+. I.E any number of digits.
Not actually a problem but a space holds no special meaning in a regexp, it is just a space so no need to capture it unless user later. Replace ( ) with just .
END of Pattern. But there may be other occurrences. Tell Postgres to continue with the above pattern until end of string. (see flag 'g').
Resulting Expression/Query: (demo here)
select regexp_replace(medication_product_posology, '([0-9]+) ', '\1','g') as new_medication_product_posology
from medications;
Match "digit space letter", capturing and the digit and letter using '([0-9]) ([A-Z])', then put them back using back references.
select REGEXP_REPLACE(medication_product_amount, '([0-9]) ([A-Z])', '\1\2') as new_medication_product_amount
from medications

How to remove any special characters from a string even with dot and comma and spaces

INPUT STRING:'HI every one. I want to (2-21-2022) remove the comma-dot and other any special character from string(123)'.
OUTPUT STRING:'HI every one I want to 2-21-2022 remove the #comma dot and other any special #character from string 123'
Thanks IN Advance.
If what you said in title:
remove any special characters from a string even with dot and comma and spaces
means that you'd want to keep only digits and letters, then such a regular expression might do:
SQL> with test (col) as
2 (select 'HI every one. I want to (2-21-2022) remove the comma-dot and other any special character from string(123)' from dual)
3 select regexp_replace(col, '[^[:alnum:]]') result
4 from test;
RESULT
---------------------------------------------------------------------------------
HIeveryoneIwantto2212022removethecommadotandotheranyspecialcharacterfromstring123
SQL>
On the other hand, that's not what example you posted represents (as already commented).

Find phone numbers with unexpected characters using SQL in Oracle?

I need to find rows where the phone number field contains unexpected characters.
Most of the values in this field look like:
123456-7890
This is expected. However, we are also seeing character values in this field such as * and #.
I want to find all rows where these unexpected character values exist.
Expected:
Numbers are expected
Hyphen with numbers is expected (hyphen alone is not)
NULL is expected
Empty is expected
Tried this:
WHERE phone_num is not like ' %[0-9,-,' ' ]%
Still getting rows where phone has numbers.
from https://regexr.com/3c53v address you can edit regex to match your needs.
I am going to use example regex for this purpose
select * from Table1
Where NOT REGEXP_LIKE(PhoneNumberColumn, '^[+]*[(]{0,1}[0-9]{1,4}[)]{0,1}[-\s\./0-9]*$')
You can use translate()
...
WHERE translate(Phone_Number,'a1234567890-', 'a') is NOT NULL
This will strip out all valid characters leaving behind the invalid ones. If all the characters are valid, the result would be NULL. This does not validate the format, for that you'd need to use REGEXP_LIKE or something similar.
You can use regexp_like().
...
WHERE regexp_like(phone_num, '[^ 0123456789-]|^-|-$')
[^ 0123456789-] matches any character that is not a space nor a digit nor a hyphen. ^- matches a hyphen at the beginning and -$ on the end of the string. The pipes are "ors" i.e. a|b matches if pattern a matches of if pattern b matches.
Oracle has REGEXP_LIKE for regex compares:
WHERE REGEXP_LIKE(phone_num,'[^0-9''\-]')
If you're unfamiliar with regular expressions, there are plenty of good sites to help you build them. I like this one

Argument '0' is out of range error

I have a query (sql) to pull out a street name from a string. It's looking for the last occurrence of a digit, and then pulling the proceeding text as the street name. I keep getting the oracle
"argument '0' is out of range"
error but I'm struggling to figure out how to fix it.
the part of the query in question is
substr(address,regexp_instr(address,'[[:digit:]]',1,regexp_count(address,'[[:digit:]]'))+2)
any help would be amazing. (using sql developer)
The fourth parameter of regexp_instr is the occurrence:
occurrence is a positive integer indicating which occurrence of
pattern in source_string Oracle should search for. The default is 1,
meaning that Oracle searches for the first occurrence of pattern.
In this case, if an address has no digits within, the regexp_count will return 0, that's not a valid occurrence.
A simpler solution, which does not require separate treatment for addresses without a house number, is this:
with t (address) as (
select '422 Hickory Str.' from dual union all
select 'One US Bank Plaza' from dual
)
select regexp_substr(address, '\s*([^0-9]*)$', 1, 1, null, 1) as street from t;
The output looks like this:
STREET
-------------------------
Hickory Str.
One US Bank Plaza
The third argument to regexp_substr is the first of the three 1's. It means start the search at the first character of address. The second 1 means find the first occurrence of the search pattern. The null means no special match modifiers (such as case insensitive - nothing like that needed here). The last 1 means "return the first SUBEXPRESSION from the match pattern". Subexpressions are parts of the match expression enclosed in parentheses.
The match pattern has a $ at the end - meaning "anchor at the end of the input string" ($ means the end of the string). Then [...] means match any of the characters in square brackets, but the ^ in [^...] changes it to match any character OTHER THAN what is in the square brackets. 0-9 means all characters between 0 and 9; so [^0-9] means match any character(s) OTHER THAN digits, and the * after that means "any number of such characters" (between 0 and everything in the input string). \s is "blank space" - if there are any blank spaces following a possible number in the address, you don't want them included right at the beginning of the street name. The subexpression is just [^0-9]* meaning the non-digits, not including any spaces before them (because the \s* is outside the left parenthesis).
My example illustrates a potential problem though - sometimes an address does, in fact, have a "number" in it, but spelled out as a word instead of using digits. What I show is in fact a real-life address in my town.
Good luck!
looking for the last occurrence of a digit, and then pulling the proceeding text as the street name
You could simply do:
SELECT REGEXP_REPLACE( address, '^(.*)\d+\D*$', '\1' )
AS street_name
FROM address_table;

Split words with a capital letter in PostgreSQL

I have sene Split words with a capital letter in sql which is applicable to MS SQL but I was wondering how to achieve the same using PostgreSQL
Basically I'm getting values such as FirstNameValue but I need it to be First Name Value
Unfortunately I don't know where to even start. I got to the following and got stuck straight away
SELECT REGEXP_REPLACE('ThoMasTest', '[^ ][A-Z].', ' ')
The result from a string such as ThoMasTest should be Tho Mas Test
Thanks
This should do the trick:
select regexp_replace('ThoMasTest', '([a-z])([A-Z])', '\1 \2','g');
The expression matches two characters next to eachother, each one in its own group:
[a-z] that matches a lowercase letter.
[A-Z] finds a capital letter
So if one lowercase if immediately followed by a capital letter insert a space between them.
Do that globally 'g'.