首页 > 解决方案 > 基于 Pandas/regex 的方法来匹配字符串列表中的第一个字符串

问题描述

如果这是交叉列出的,请道歉;我找了一会儿!

我正在处理 Pandas 中一些非常大、非常混乱的数据。感兴趣的变量是一个字符串,并且包含一个或多个带有(没有)典型业务后缀的业务名称实例(例如,LLC、LP、LTD)。例如,我可能有“ABC LLC XYZ,LLC XYZ, LTD”。我的目标是找到从列表中匹配的后缀的第一个实例。我还需要提取第一场比赛之前的所有内容。对于上面的例子,我只想找到/提取“ABC LLC”。考虑以下数据:

 sfx = ['LLC','LP','LTD']
 dat = pd.DataFrame({'name':['ABC LLC XYZ,LLC XYZ, LTD','IJK LP, ADDRESS']})

到目前为止,我已经以一种不适合我的复杂方式完成了一个案例:

one_string = 'ABC LLC XYZ,LLC XYZ, LTD'
indexes=[]
keywords=dict()
for sf in sfx:
    indexes.append(one_string.index(sf,0))
    keywords[one_string.index(sf,0)]=sf
    indexes.sort()
    print(one_string[0:indexes[0]]+ keywords[indexes[0]])

我正在寻找一种更有效(可能矢量化)的方式来为整个列执行此操作。此外,我需要合并正则表达式以避免在文本中恰好出现相同的字母组合时提取后缀。我需要匹配的正则表达式模式可能看起来像这样(LLC 出现在空格或逗号之后,并且位于单词的末尾):

reg_pattern = r`(?<=[\s\,])LLC\b|(?<=[\s\,])LP\b|(?<=[\s\,])LTD\b`

更新

Wiktor 的直接解决方案。我还意识到,一旦我提取了后缀之前的内容,我就需要单独提取它之后的所有内容。将解决方案投入到积极的背后是行不通的。非常欣赏!

标签: pythonregexpandas

解决方案


要获取之前并包含关键字的文本,您可以使用

pattern = r"^(.*?\b(?:{}))(?!\w)".format("|".join(map(re.escape, names)))

进而

df['results'] = df['texts'].str.extract(pat, expand=False)

调整列名以匹配您的代码。该模式看起来像^(.*?\b(?:LLC|LP|LTD))(?!\w)并且将意味着:

  • ^- 字符串的开始
  • (.*?\b(?:LLC|LP|LTD))- 第 1 组(此值将由 返回.str.extract):
    • .*?- 除换行符以外的任何 0+ 字符,尽可能少
    • \b- 单词边界
    • (?:LLC|LP|LTD)- 备选方案之一:LLC,LPLTD
  • (?!\w)- 后面不跟单词 char:字母、数字或_.

要在匹配后获取所有文本,您可以使用

pattern = r"\b(?:{})(?!\w)(.*)".format("|".join(map(re.escape, names)))

在这里,模式看起来像\b(?:LLC|LP|LTD))(?!\w)(.*),它首先将其中一个名称作为一个完整的单词进行匹配,然后将行的所有其余部分捕获到第 1 组中(匹配(.*)- 除换行符之外的任何 0 个或多个字符)。


推荐阅读