Home > Software design >  Extract text :after the last white space and that is in capital letters from last , ignoring dot(.)
Extract text :after the last white space and that is in capital letters from last , ignoring dot(.)

Time:02-19

I have a text column, which basically has kind of notes, and most of the notes end with 2 to 3 capital letters after the last space in the text as in below 2 examples. And I need to extract those last characters which come after the last space into a new column either in pandas or in sql. And they should be extracted only if they are in capital letters, else null.

Ex 1 - 5723452309423 | NA | customer cancelled purchase| refund given | 12.3.2021 | approver is BG

Ex 2 - 54986866 | NA | customer order returned| refund has been given | 12.4.2021 | AKS

Ex 3 - 54986866 | NA | customer order returned| refund has been given | 12.4.2021 | KSR.

Ex 4 - 54986866 | NA | customer order returned| refund has been given | 12.4.2021 | approved by LS and processed.**

enter image description here enter image description here

CodePudding user response:

If those are just strings then you can use string.split(" ")[-1] to retrieve the last part.

my_str = "5723452309423 | NA | customer cancelled purchase| refund given | 12.3.2021 | approver is BG"
my_str.split(" ")[-1]

output is "BG" then you can use string.isupper() to check the case.

my_str.split(" ")[-1].isupper()

output is True

CodePudding user response:

df = pd.DataFrame({
    "col1": ["approver is BG", " AKS"]
})

df["col2"] = df["col1"].str.split(" ").str[-1]

df is:

          col1 col2
approver is BG   BG
           AKS  AKS

CodePudding user response:

You can use a regex to explicitly select 2/3 upper case characters in the end:

df['new'] = df['note'].str.extract(r'([A-Z]{2,3}$)')

Or more generally for the last chunk rsplit:

df['new'] = df['note'].str.rsplit('\s ', n=1).str[-1]

CodePudding user response:

If you want to do this in SQL you can ignore how many strings there are by reversing the string before cracking it apart with OPENJSON() and then reversing it again once the last element is extracted. Checking for upper case is a little cumbersome in SQL Server as well; for big lumpy and irregular strings like this you're almost certainly better off doing this in Python.

Still, given this data:

CREATE TABLE dbo.SomeTable(ID int IDENTITY, SomeColumn varchar(500));

INSERT dbo.SomeTable(SomeColumn) VALUES
('this is pure garbage.'),
('this is NOT'),
('this is JUNK'),
('5723452309423 | NA | customer cancelled purchase'
    '| refund given | 12.3.2021 | approver is BG'),
('Ex 2 - 54986866 | NA | customer order returned'
    '| refund has been given | 12.4.2021 | AKS');

This query, which I've made intentionally protective and cumbersome to illustrate why SQL Server isn't the place to do this:

;WITH x(ID, str) AS
(
  SELECT ID, REVERSE(JSON_VALUE(x.value, N'$.a'))
  FROM dbo.SomeTable AS s CROSS APPLY OPENJSON 
    ('[{"a":"' 
        REPLACE(STRING_ESCAPE(REVERSE(SomeColumn), 'json'), ' ', '"},{"a":"') 
        '"}]') 
  AS x WHERE [key] = 0
)
SELECT ID, str FROM x
WHERE LEN(str) IN (2,3) 
  AND     str  COLLATE Latin1_General_BIN 
  = UPPER(str) COLLATE Latin1_General_BIN;

Returns this data:

ID str
2 NOT
4 BG
5 AKS

CodePudding user response:

your data in table

declare @a TABLE ( note varchar(max));
INSERT @a(note) VALUES
('5723452309423 | NA | customer cancelled purchase| refund given | 12.3.2021 | approver is BG'),
('54986866 | NA | customer order returned| refund has been given | 12.4.2021 | AKS'),
('58735980490 | NA | order cancelled refund requested| refund processed | 15.4.2021 |processed by : LO'),
('983943795803 | NA |_ refund asked by account owner| refunded')

In SQL you can use this query

select note,iif(lastValue = UPPER(lastValue) COLLATE SQL_Latin1_General_CP1_CS_AS,lastValue, null ) init1 from
(select note,right(rtrim(note),charindex(' ',reverse(rtrim(note)) ' ')-1) lastValue from @a) b
  • Related