【问题标题】:Python - Replace() for a list of keywordsPython - Replace() 用于关键字列表
【发布时间】:2020-12-22 01:39:17
【问题描述】:

我有一个公司列表,上面有他们的名字+业务缩写,例如:

['Abc Inc','def Gmbh','ghi PLC', 'xhlm SA', 'sojs LLC'] and so on. 

我想获得一个没有 PLC、INC、Gmbh 以及类似的首字母缩略词的干净列表。出于这个原因,我添加了一个 for 循环,该循环遍历首字母缩略词列表,以将其从公司名称中删除并替换为“”。

这就是我带来的,但会大大增加处理我的代码所需的时间。有更好的主意吗?

def ExtractNames():

substring_adjustment = ['AB', 'AB', 'B.V', 'B.v', 'BV', 'BV', 'GMBH', 'Gmbh', 'INC', 'INC.', 'Inc', 'Inc.', 'LTD', 'Ltd', 'NV', 'NV', 'P.L.C', 'P.L.C', 'PLC', 'Plc', 'SA', 'SE', 'SE', 'SPA', 'Sa', 'Spa', 'ab', 'b.v', 'bv', 'gmbh', 'inc', 'inc.', 'ltd', 'nv', 'p.l.c', 'plc', 'sa', 'se', 'spa',",",".","-"]  
Company_List= load_workbook(filename='Excel for Scraping.xlsx',data_only=True).active 

for row in Company_List.iter_rows (min_row=2,min_col=1,max_col=1,values_only=True): 
    value = row[0]
    for word in substr_adjust:
        value = value.replace(word,"")
        print(value)

【问题讨论】:

  • @erip:这只适用于用其他东西替换单个字符; OP 有要替换的多字符串。
  • 你可以使用某种正则表达式。
  • 在未来的 3.9 中,你可以使用str.removesuffix 来解决这个问题。然而,可能不会像正则表达式解决方案那样快。
  • @HampusLarsson:非常好的建议!但这仅适用于固定字符串,不是吗?这不只是endswith() 的包装吗?
  • @Jan 您可以在PEP 616 中了解更多信息。它基本上既是endswith(),又是给定字符串的索引切片。你是对的,它只会使用固定的字符串。

标签: python loops for-loop time replace


【解决方案1】:

您可以加入替换并使用正则表达式:

import re
substring_adjustment = ['AB', 'AB', 'B.V', 'B.v', 'BV', 'BV', 'GMBH', 'Gmbh', 'INC', 'INC.', 'Inc', 'Inc.', 'LTD', 'Ltd', 'NV', 'NV', 'P.L.C', 'P.L.C', 'PLC', 'Plc', 'SA', 'SE', 'SE', 'SPA', 'Sa', 'Spa', 'ab', 'b.v', 'bv', 'gmbh', 'inc', 'inc.', 'ltd', 'nv', 'p.l.c', 'plc', 'sa', 'se', 'spa',",",".","-"]
lst = ['Abc Inc','def Gmbh','ghi PLC', 'xhlm SA', 'sojs LLC']

rx = re.compile(r'\s*(?:{})$'.format("|".join(substring_adjustment)))

new_list = [rx.sub('', item) for item in lst]
print(new_list)
# ['Abc', 'def', 'ghi', 'xhlm', 'sojs LL']

如您所见,这种方法的问题在于您需要先放置较长的替换。此外,您的替换列表中有重复项。
话虽如此,您可以将替换列表和正则表达式更改为:

import re

substring_adjustment = ['AB', 'B\.?V', 'GMBH', 'INC\.?', 'LTD', 'NV', 'P\.?L\.?C', 'S[AE]', 'SPA']
lst = ['Abc Inc', 'def Gmbh', 'ghi PLC', 'xhlm SA', 'sojs LLC', 'XXX Management Limited']

rx = re.compile(r'(?i)\s*\b(?:{})$'.format("|".join(substring_adjustment)))

new_list = [rx.sub('', item) for item in lst]
print(new_list)

为您的示例产生的结果:

['Abc', 'def', 'ghi', 'xhlm', 'sojs LLC', 'XXX Management Limited']

【讨论】:

  • 谢谢!我正在阅读正则表达式文档以了解您输入的每个字符。在运行代码时,我发现了一个问题:它对于有首字母缩写词的公司非常有效,但对于没有首字母缩写词的公司,在某些情况下它会删除最后一个字母,以便理解原因。 XXX Management Limited -> XXX Management Limited YYY Corporation -> YYY Corporatio ZZZ Malaysia -> ZZZ Malaysi
  • @AdrianoPatruno:取第二个正则表达式而不是第一个。
【解决方案2】:

首先,您只需替换公司名称的可能部分

company_name = "ABBA AB"
print(company_name.replace("AB", ""))
# 'BA '

也许您想拆分您的 company_name 字符串,而不是分别过滤值

substring_adjustment_set = {'AB', 'B.V', 'B.v', 'BV', 'GMBH', 'Gmbh'}
string_list = company_name.split(" ")
result = " ".join(filter(lambda x: x not in substring_adjustment_set, string_list))
print(result) 
# ABBA

【讨论】:

    【解决方案3】:

    而不是遍历值中可能存在的所有子字符串(然后使用replace,这可能存在其他问题,例如,如果公司名称中的单词包含“ab”为一个子字符串),您可以创建一组子字符串并遍历公司名称中的单词,测试它们是否被列出,并将那些没有的单词连接在一起(使用空格分隔符)。集包含测试是 O(1) 时间,所以它不应该那么慢。

    substring_adjustment = {'AB', 'AB', 'B.V', 'B.v', 'BV', 'BV', 'GMBH', 'Gmbh', 'INC', 'INC.', 'Inc', 'Inc.', 'LTD', 'Ltd', 'NV', 'NV', 'P.L.C', 'P.L.C', 'PLC', 'Plc', 'SA', 'SE', 'SE', 'SPA', 'Sa', 'Spa', 'ab', 'b.v', 'bv', 'gmbh', 'inc', 'inc.', 'ltd', 'nv', 'p.l.c', 'plc', 'sa', 'se', 'spa',",",".","-"}
    
    
    for value in ['Abc Inc','def Gmbh','ghi PLC', 'xhlm SA', 'sojs LLC']:
    
        print(' '.join(word for word in value.split()
                       if word not in substring_adjustment))
    

    给予:

    Abc
    def
    ghi
    xhlm
    sojs LLC
    

    另请注意,substring_adjustment 的表达式实际上有一些重复项(例如 'AB''BV'),但这些将在您创建集合时自动处理。

    【讨论】:

    • 它运行良好,将我的处理时间缩短了 20%。谢谢!
    【解决方案4】:

    使用正则表达式,您可能会比这更快:

    import re
    
    def ExtractNames():
        substring_adjustment = ['AB', 'AB', 'B.V', 'B.v', 'BV', 'BV', 'GMBH', 'Gmbh', 'INC', 'INC.', 'Inc', 'Inc.', 'LTD', 'Ltd', 'NV', 'NV', 'P.L.C', 'P.L.C', 'PLC', 'Plc', 'SA', 'SE', 'SE', 'SPA', 'Sa', 'Spa', 'ab', 'b.v', 'bv', 'gmbh', 'inc', 'inc.', 'ltd', 'nv', 'p.l.c', 'plc', 'sa', 'se', 'spa',",",".","-"]  
        removal_regex = '|'.join(re.escape(word) for word in substring_adjustment)
        # 'AB|AB|B\\.V|B\\.v|BV|BV|...'
        for row in Company_List.iter_rows(min_row=2, min_col=1, max_col=1, values_only=True):
            value = re.sub(removal_regex, '', row[0])
    

    【讨论】:

      猜你喜欢
      • 2020-05-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-08
      • 2020-09-11
      • 1970-01-01
      • 1970-01-01
      • 2017-05-23
      相关资源
      最近更新 更多