当前位置: 代码迷 >> python >> 如何避免需要递归使用正则表达式删除字符串末尾的单词?
  详细解决方案

如何避免需要递归使用正则表达式删除字符串末尾的单词?

热度:35   发布时间:2023-06-13 14:00:22.0

我想删除出现在字符串末尾的术语。 例如, LTDCORPLLCINC [总共有大约50个不同的术语我想从字符串末尾删除]。

我的问题是如何删除这些术语的序列,例如使用字符串“COMPANY_NAME CORP LTD”。 在这种情况下,我想删除CORPLTD [即一旦LTD已被删除,该术语现在以CORP结束,我也想要消失]。

目前,我递归地执行此操作,一遍又一遍地运行正则表达式,直到它不再进行更改。

import re

def re_run_match(match_term, replace_with, string):
    new_string_temp = re.subn(match_term, replace_with, string)
    if new_string_temp[1] == 0:
        return(new_string_temp[0])
    else:
        return(re_run_match(match_term, replace_with, new_string_temp[0]))

long_match_set = r" LTD$| CORP$| LLC$| INC$"
company_name = "COMPANY_NAME CORP LTD"
clean_company_name = re_run_match(long_match_set, "", company_name)

在没有递归的情况下,有没有比这更简单的方法? 目前,在没有进一步调整之前,每个字符串往往需要通过正则表达式命令大约2-3次,因此使代码比在单个操作中有一种方法慢2或3倍。

注意:我不想删除不在字符串末尾的术语,因此我不仅仅使用匹配术语,例如r"\\bLTD\\b|\\bCORP\\b|\\bLLc\\b|b\\INC\\b"

你可以通过分组和+量词实现它:

import re
long_match_set = r"(?: (?:LTD|CORP|LLC|INC))+$"
company_name = "COMPANY_NAME CORP LTD"
clean_company_name = re.sub(long_match_set, "", company_name)
print(clean_company_name)

请参阅

正则表达式匹配1个或更多组( +

  • 一个空间和一个替代组,包括
    • LTDCORPLLCINC之前
  • $ - 结束字符串。

我们的想法是匹配在字符串结尾之前按顺序排列的任何space + keyword

观察:

In [1]: import re

In [2]: %timeit re.compile('( (ltd|corp|llc|inc))+$', re.IGNORECASE).sub('', 'COMPANY_NAME CORP LTD')
100000 loops, best of 3: 2.51 ?s per loop

In [3]: %timeit re.compile('(?: (?:ltd|corp|llc|inc))+$', re.IGNORECASE).sub('', 'COMPANY_NAME CORP LTD')
100000 loops, best of 3: 2.48 ?s per loop

?:更快但不是很多而忽略了区分大小写。

In [4]: %timeit re.compile('(?: (?:ltd|corp|llc|inc))+$').sub('', 'COMPANY_NAME CORP LTD')
100000 loops, best of 3: 2.03 ?s per loop

In [5]: %timeit re.compile('( (ltd|corp|llc|inc))+$').sub('', 'COMPANY_NAME CORP LTD')
100000 loops, best of 3: 2.2 ?s per loop

忽略区分大小写,它的速度要快得多。

In [6]: %timeit re.compile('( (ltd|corp|llc|inc))+$').sub('', 'COMPANY_NAME CORP LTD wont match')
100000 loops, best of 3: 2.61 ?s per loop

In [7]: %timeit re.compile('(?: (?:ltd|corp|llc|inc))+$').sub('', 'COMPANY_NAME CORP LTD wont match')
100000 loops, best of 3: 2.58 ?s per loop

并且在NO MATCH它会更快一点。

我建议你使用?: