【问题标题】:Get a specific string with Regex in Python在 Python 中使用正则表达式获取特定字符串
【发布时间】:2021-03-23 13:27:45
【问题描述】:

我的字符串如下所示:

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 次破折号之后超过某个字符阈值?它是否与 3 个字母字符后跟 4 个或 5 个数字字符有关?或者,您是否只在一定数量的字符之上或之间寻找字符串而不考虑位置?看看我对后者的回答。

标签: python python-3.x regex pandas python-2.7


【解决方案1】:

看起来您根本不需要正则表达式。为什么不直接拆分字符串并获取每个字符串的倒数第三个元素:

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

如果您的数据在感兴趣的子字符串之后更不规则,另一种可能的方法是拆分您的字符串并返回最长的子字符串:

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

如果你必须使用正则表达式并且你的模式看起来像你展示的那样,那么你也可以使用:

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

【讨论】:

    【解决方案2】:

    另一种在匹配后查找 2 个 - 单独子字符串的方法:

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

    【讨论】:

      【解决方案3】:

      使用 Series.str.extract 搜索 3 个字母后跟 4-5 数字:

      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
      

      【讨论】:

        【解决方案4】:

        您可以使用以下正则表达式搜索 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
        

        【讨论】:

          【解决方案5】:

          从右侧开始计数,然后所有代码都在第三个破折号中。您可以做的是反转字符串,然后在获得结果后再次反转它。如果格式不稳定,则找到其他方法,例如计算破折号之间的代码长度,当它与要求匹配时,接受或打印。

          【讨论】:

          • 不,我认为这很好用。你介意让我知道如何逆转吗?
          • @SaraDaniel df['A'] = df['A'].apply(lambda x: x[::-1])
          • 我想你现在明白了,抱歉回复晚了
          猜你喜欢
          • 1970-01-01
          • 2023-01-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-04-08
          • 2019-03-13
          • 2014-02-08
          • 1970-01-01
          相关资源
          最近更新 更多