【问题标题】:str.extract() with regexstr.extract() 与正则表达式
【发布时间】:2022-01-20 12:21:35
【问题描述】:

我需要使用正则表达式和str.extract() 将一列分成两部分(假设这是最好的)

    df = pd.DataFrame({
                        'Product': ['Truly Mix 2/12Pk Cans - 12Z',
                                    'Bud 16Z - LOOSE -  16Z',
                                    'Blue Moon (Case 12x - 22Z)',
                                    '2 for the show (6/4PK - 16Z)']
             })

我想要这个结果:

df_result = pd.DataFrame({
                          'Product': ['Truly Mix', 'Bud', 'Blue Moon', '2 for the show'],
                          'Packaging': ['2/12Pk Cans - 12Z',
                                        '16Z - LOOSE -  16Z',
                                        'Case 12x - 22Z',
                                        '6/4PK - 16Z' ]
                 })

我尝试了很多东西,但仍然在使用正则表达式时遇到了困难,即使经过大量的在线学习。

这是我获得产品的最后尝试:

pattern = r'(\D+)[^\w][^(Case][^0-9]'

df['Product'] = df['Product'].str.extract(pattern)

str.replace() 应该可以很好地摆脱括号,只是不能走那么远。

我只是在 3 小时后还没有关闭。

【问题讨论】:

    标签: regex pandas


    【解决方案1】:

    您可以将每个条目的两个部分提取到两列中,然后在它们所在的字符串的开头/结尾删除()

    import pandas as pd
    df = pd.DataFrame({'Product': ['Truly Mix 2/12Pk Cans - 12Z','Bud 16Z - LOOSE -  16Z','Blue Moon (Case 12x - 22Z)','2 for the show (6/4PK - 16Z)']})
    pattern = r'^(.*?)\s*((?:\((?:Case\b)?|\d+(?:/\d+)?[A-Za-z]+\b).*)'
    df[['Product', 'Packaging']] = df['Product'].str.extract(pattern, expand=True)
    df['Packaging'] = df['Packaging'].str.replace(r'^\((.*)\)$', r'\1', regex=True)
    # => >>> print(df['Packaging'])
    #    0     2/12Pk Cans - 12Z
    #    1    16Z - LOOSE -  16Z
    #    2        Case 12x - 22Z
    #    3           6/4PK - 16Z
    # => >>> print(df['Product'])
    #    0         Truly Mix
    #    1               Bud
    #    2         Blue Moon
    #    3    2 for the show
    

    请参阅regex demo正则表达式详细信息

    • ^ - 字符串开头
    • (.*?) - 第 1 组:除换行符之外的任何零个或多个字符尽可能少 -\s* - 零个或多个空格
    • ((?:\((?:Case\b)?|\d+(?:/\d+)?[A-Za-z]+\b).*) - 第 2 组:
      • (?:\((?:Case\b)?|\d+(?:/\d+)?[A-Za-z]+\b) - 任何一个
        • \((?:Case\b)? - 一个(,然后是一个可选的整个单词Case
        • | - 或
        • \d+(?:/\d+)?[A-Za-z]+\b - 一个或多个数字,/ 和一个或多个数字的可选序列,以及一个或多个字母(后跟单词边界)
      • .* - 除换行符之外的任何零个或多个字符尽可能多

    .replace(r'^\((.*)\)$', r'\1', regex=True) 部分删除了字符串开头和结尾处的()

    【讨论】:

      猜你喜欢
      • 2019-08-28
      • 2010-09-12
      • 2011-08-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-04
      • 2017-12-18
      • 2017-09-27
      相关资源
      最近更新 更多