Get a specific string with Regex in Python

Viewed 414

I have strings that look alike as below:

ART-B-C-ART0015-D-E01
ADC-B-C-ADC00112-V-E01
AEE-B-C-AEE00011-D-E01
AQW-B-C-AQW0013-D-E01
AAZ-B-C-AAZ0014-D-E01
AQQ-B-C-AQQ0032-D-E01
ADD-B-C-D-ADD0001-D-E01
AAA-B-C-AAA0012-D-E01

I want to have the below result: Expected Result:

ART0015
ADC00112
AEE00011
AQW0013
AAZ0014
AQQ0032
ADD0001
AAA0012

I used the below regex code and unfortunately, I don't get the expected result, due to the 7th record is not in the third dash. it is in the fourth dash.

df["A"].str.extract(r'^(?:[^-]*-){3}\s*([^-]+)', expand=False)

0     ART0015
1    ADC00112
2    AEE00011
3     AQW0013
4     AAZ0014
5     AQQ0032
6        D
7     AAA0012
5 Answers

Use Series.str.extract by searching for 3 letters followed by 4-5 numbers:

In [477]: df['col'] = df['col'].str.extract(r'([a-zA-Z]{3}\d{4,5})')

In [478]: df
Out[478]: 
0   ART0015
1  ADC00112
2  AEE00011
3   AQW0013
4   AAZ0014
5   AQQ0032
6   ADD0001
7   AAA0012

Another approach that looks for 2 - separate substrings after your match:

>>> df['A'].str.extract(r'([^-]+)(?:-[^-]*){2}$')
          0
0   ART0015
1  ADC00112
2  AEE00011
3   AQW0013
4   AAZ0014
5   AQQ0032
6   ADD0001
7   AAA0012

You can use the following regex to search for 7 or 8 repeating alphanumeric characters, with the output prioritizing the higher:

df['A'] = df['A'].str.extract('-([A-Za-z0-9]{7,8})-')

      A
0   ART0015
1   ADC00112
2   AEE00011
3   AQW0013
4   AAZ0014
5   AQQ0032
6   ADD0001
7   AAA0012

Looks like you don't need regular expressions at all. Why don't you just split your string and get the third to last element per string:

df["A"].str.split('-').str[-3]

Example:

import pandas as pd

d = {'A': ['ART-B-C-ART0015-D-E01', 'ADC-B-C-ADC00112-V-E01']}
df = pd.DataFrame(data=d)
df['A'] = df["A"].str.split('-').str[-3]

print(df)

Prints:

          A
0   ART0015
1  ADC00112

Another possible approach would be to split your strings and return the longest substring if your data is more irregular after the substrings of interest:

df['A']= df['A'].apply(lambda s: max(s.split('-'), key=len))

And if you must use regular expressions and your patterns look like as you have shown, then you could also use:

df['A']= df['A'].str.extract(r'([^-]{4,})')

start counting from right side then all codes are in third dash. What you can do is reverse the string and then after getting result reverse it again. If the format is not stable then find other way like count the length of code between dashes and when it matches the required then accept it or print it.

Related