Python Pandas正则表达式:搜索列中带有通配符的字符串并返回匹配项

时间:2019-04-14 08:25:34

标签: python regex pandas wildcard-expansion

我在一个可能包含关键字的列中有一个搜索列表:'keyword1*keyword2',试图在单独的数据框列中找到匹配项。如何包含正则表达式通配符类型'keyword1.*keyword2' #using str.extract, extractall or findall?

使用.str.extract可以很好地匹配完全匹配的子字符串,但是我还需要它也可以使子字符串与关键字之间的通配符匹配。

# dataframe column or series list as keys to search for: 
dfKeys = pd.DataFrame()
dfKeys['SearchFor'] = ['this', 'Something', 'Second', 'Keyword1.*Keyword2', 'Stuff', 'One' ]

# col_next_to_SearchFor_col
dfKeys['AdjacentCol'] = ['this other string', 'SomeString Else', 'Second String Player', 'Keyword1 Keyword2', 'More String Stuff', 'One More String Example' ]

# dataframe column to search in: 
df1['Description'] = ['Something Here','Second Item 7', 'Something There', 'strng KEYWORD1 moreJARGON 06/0 010 KEYWORD2 andMORE b4END', 'Second Item 7', 'Even More Stuff']]

# I've tried:
df1['Matched'] = df1['Description'].str.extract('(%s)' % '|'.join(key['searchFor']), flags=re.IGNORECASE, expand=False)

我也尝试用上面的代码用'extractall'和'findall'代替'extract',但是它仍然不能满足我的需要。 我期望'Keyword1*Keyword2'"strng KEYWORD1 moreJARGON 06/0 010 KEYWORD2 andMORE b4END"匹配

更新:“。*”有效! 我还在尝试将来自“ SearchFor”列中匹配键旁边的单元格的值添加到该值,即dfKeys['AdjacentCol']

我尝试过:     df1['From_AdjacentCol'] = df1['Description'].str.extract('(%s)' % '|'.join(key['searchFor']), flags=re.IGNORECASE, expand=False).map(dfKeys.set_index('SearchFor')['AdjacentCol'].to_dict()).fillna('')可以用于通配符以外的所有键。

# expected:
  Description                                      Matched            From_AdjacentCol
0 'Something Here'                                 'Something'         'this other string'
1 'Second Item 7'                                  'Second'            'Second String Player'
2 'Something There'                                'Something'         'this other string'  
3 'strng KEYWORD1 moreJARGON 06/0 010 KEYWORD2...' 'Keyword1*Keyword2' 'Keyword1 Keyword2'
4 'Second Item 7'                                  'Second'            'Second String Player'
5 'Even More Stuff'                                'Stuff'             'More String Stuff'

在此方面的任何帮助都将受到赞赏。谢谢!

1 个答案:

答案 0 :(得分:0)

解决方案

您已接近解决方案,只需将*更改为.*。读取docs

  

。       (点)在默认模式下,它匹配换行符以外的任何字符。如果指定了DOTALL标志,则匹配任何   包括换行符的字符。

     

*       使结果RE与前面的RE的0个或多个重复匹配,并尽可能多地重复。 ab *将匹配“ a”,   “ ab”或“ a”,后跟任意数量的“ b”。

在正则表达式中,单独的星形符号*无效。它与Unix / Windows文件系统中的常规glob运算符*具有不同的含义。

星号是一个量词(即 gready量词),它必须与某种模式相关联(此处为.以匹配任何字符)以表示某些含义。

MCVE

重塑您的MCVE:

import re
import pandas as pd

keys = ['this', 'Something', 'Second', 'Keyword1.*Keyword2', 'Stuff', 'One' ]

df1 = pd.DataFrame()
df1['Description'] = ['Something Here','Second Item 7', 'Something There',
                      'strng KEYWORD1 moreJARGON 06/0 010 KEYWORD2 andMORE b4END',
                      'Second Item 7', 'Even More Stuff']


regstr = '(%s)' % '|'.join(keys)

df1['Matched'] = df1['Description'].str.extract(regstr, flags=re.IGNORECASE, expand=False)

正则表达式现在为:

(this|Something|Second|Keyword1.*Keyword2|Stuff|One)

并匹配丢失的情况:

                                         Description                                Matched
0                                     Something Here                              Something
1                                      Second Item 7                                 Second
2                                    Something There                              Something
3  strng KEYWORD1 moreJARGON 06/0 010 KEYWORD2 an...  KEYWORD1 moreJARGON 06/0 010 KEYWORD2
4                                      Second Item 7                                 Second
5                                    Even More Stuff                                  Stuff