首页 > 解决方案 > 在不区分大小写的搜索期间提取与模式中使用的原始大小写的匹配项

问题描述

在进行正则表达式模式匹配时,我们得到匹配的内容。如果我想要在内容中找到的模式怎么办?

请参见以下示例:

>>> import re
>>> r = re.compile('ERP|Gap', re.I)
>>> string = 'ERP is integral part of GAP, so erp can never be ignored, ErP!'
>>> r.findall(string)
['ERP', 'GAP', 'erp', 'ErP']

但我希望输出看起来像这样:['ERP', 'Gap', 'ERP', 'ERP']

因为如果我对原始输出进行分组和求和,我会得到以下输出作为数据框:

ERP 1
erp 1
ErP 1
GAP 1
gap 1

但是如果我希望输出看起来像

ERP 3
Gap 2

与我要搜索的关键字一致吗?

更多内容

我有一个这样的关键字列表:['ERP', 'Gap']. 我有一个这样的字符串:"ERP, erp, ErP, GAP, gap"

我想计算每个关键字在字符串中出现的次数。现在,如果我正在进行模式匹配,我将得到以下输出:[ERP, erp, ErP, GAP, gap].

现在,如果我想汇总并计数,我将得到以下数据框:

ERP 1
erp 1
ErP 1
GAP 1
gap 1

虽然我希望输出看起来像这样:

ERP 3
Gap 2

标签: pythonregex

解决方案


您可以动态构建模式以在组名中包含您搜索的单词的索引,然后获取匹配的那些模式部分:

import re

words = ["ERP", "Gap"]
words_dict = { f'g{i}':item for i,item in enumerate(words) } 

rx = rf"\b(?:{'|'.join([ rf'(?P<g{i}>{item})' for i,item in enumerate(words) ])})\b"

text = 'ERP is integral part of GAP, so erp can never be ignored, ErP!'

results = []
for match in re.finditer(rx, text, flags=re.IGNORECASE):
    results.append( [words_dict.get(key) for key,value in match.groupdict().items() if value][0] )

print(results) # => ['ERP', 'Gap', 'ERP', 'ERP']

在线查看Python 演示

该模式将如下所示\b(?:(?P<g0>ERP)|(?P<g1>Gap))\b

  • \b- 单词边界
  • (?:- 封装模式部分的非捕获组的开始:
    • (?P<g0>ERP)- 组“g0”:ERP
    • |- 或者
    • (?P<g1>Gap)- 组“g1”:Gap
  • )- 小组结束
  • \b- 单词边界。

请参阅正则表达式演示

注意[0]with[words_dict.get(key) for key,value in match.groupdict().items() if value][0]将适用于所有情况,因为当有匹配时,只有一个组匹配。


推荐阅读