在 Python 中使用正则表达式获取特定字符串
Get a specific string with Regex in Python
我的字符串如下所示:
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
我想要得到以下结果:
预期结果:
ART0015
ADC00112
AEE00011
AQW0013
AAZ0014
AQQ0032
ADD0001
AAA0012
我使用了下面的正则表达式代码,不幸的是,我没有得到预期的结果,因为第 7 条记录不在第三条破折号中。它在第四个破折号中。
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
通过搜索 3 个字母后跟 4-5
个数字来使用 Series.str.extract
:
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
从右侧开始计数然后所有代码都在第三个破折号中。你可以做的是反转字符串,然后在得到结果后再次反转它。如果格式不稳定,则寻找其他方法,例如计算破折号之间的代码长度,当它符合要求时,然后接受或打印它。
您可以使用以下正则表达式搜索 7 或 8 个重复的字母数字字符,输出优先级较高:
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
看来您根本不需要正则表达式。为什么不拆分字符串并获取每个字符串的倒数第三个元素:
df["A"].str.split('-').str[-3]
示例:
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)
打印:
A
0 ART0015
1 ADC00112
另一种可能的方法是拆分您的字符串和 return 最长的子字符串,如果您的数据在感兴趣的子字符串之后更不规则:
df['A']= df['A'].apply(lambda s: max(s.split('-'), key=len))
如果您必须使用正则表达式并且您的模式看起来像您所展示的那样,那么您还可以使用:
df['A']= df['A'].str.extract(r'([^-]{4,})')
另一种在匹配后查找 2 -
个单独子字符串的方法:
>>> df['A'].str.extract(r'([^-]+)(?:-[^-]*){2}$')
0
0 ART0015
1 ADC00112
2 AEE00011
3 AQW0013
4 AAZ0014
5 AQQ0032
6 ADD0001
7 AAA0012
我的字符串如下所示:
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
我想要得到以下结果: 预期结果:
ART0015
ADC00112
AEE00011
AQW0013
AAZ0014
AQQ0032
ADD0001
AAA0012
我使用了下面的正则表达式代码,不幸的是,我没有得到预期的结果,因为第 7 条记录不在第三条破折号中。它在第四个破折号中。
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
通过搜索 3 个字母后跟 4-5
个数字来使用 Series.str.extract
:
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
从右侧开始计数然后所有代码都在第三个破折号中。你可以做的是反转字符串,然后在得到结果后再次反转它。如果格式不稳定,则寻找其他方法,例如计算破折号之间的代码长度,当它符合要求时,然后接受或打印它。
您可以使用以下正则表达式搜索 7 或 8 个重复的字母数字字符,输出优先级较高:
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
看来您根本不需要正则表达式。为什么不拆分字符串并获取每个字符串的倒数第三个元素:
df["A"].str.split('-').str[-3]
示例:
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)
打印:
A
0 ART0015
1 ADC00112
另一种可能的方法是拆分您的字符串和 return 最长的子字符串,如果您的数据在感兴趣的子字符串之后更不规则:
df['A']= df['A'].apply(lambda s: max(s.split('-'), key=len))
如果您必须使用正则表达式并且您的模式看起来像您所展示的那样,那么您还可以使用:
df['A']= df['A'].str.extract(r'([^-]{4,})')
另一种在匹配后查找 2 -
个单独子字符串的方法:
>>> df['A'].str.extract(r'([^-]+)(?:-[^-]*){2}$')
0
0 ART0015
1 ADC00112
2 AEE00011
3 AQW0013
4 AAZ0014
5 AQQ0032
6 ADD0001
7 AAA0012