在Python的重新编译中合并特殊字符

2024-09-29 02:23:33 发布

您现在位置:Python中文网/ 问答频道 /正文

简明描述

我在一个项目中工作,我有一个关键字列表(其中有特殊字符)和一个字符串,我必须检查该字符串中是否存在任何关键字,并提取相同的关键字。这将是一个不区分大小写的搜索。但确切的关键字必须存在。如果SAP是一个关键字,那么sap是一个正命中,而saphire是一个负命中

我已经付出了很多努力,但我只能实现我所期望的部分产出

这是供您理解的示例代码:

>>> keywords = ["HIPAA", "ERP(2.0)"]
>>> r = re.compile('|'.join([r'\b%s\b' % w for w in keywords]), flags=re.I)
>>> word = "HIPAAA and ERP(2.0)"
>>> r.findall(word)
['']

这里我应该得到这个输出-["ERP(2.0)"]

我已经检查了这个问题:Escape regex special characters in a Python string但这并没有真正回答我的问题

考虑到我有10个具有特殊特征的关键字,并且我正在从MySQL导入这些关键字,有谁能指导我如何进行这项工作

详细说明

测试1

>>> keywords = ["HIPAA", "ERP"]
>>> r = re.compile('|'.join([r'\b%s\b' % w for w in keywords]), flags=re.I)
>>> word = "HIPAA and ERP"
>>> r.findall(word)
['HIPAA', 'ERP']

测试2

>>> keywords = ["HIPAA", "ERP(2.0)"]
>>> r = re.compile('|'.join([r'\b%s\b' % w for w in keywords]), flags=re.I)
>>> word = "HIPAA and ERP(2.0)"
>>> r.findall(word)
['']

测试3

>>> keywords = ["HIPAA", "ERP\(2.0\)"]
>>> r = re.compile('|'.join([r'\b%s\b' % w for w in keywords]), flags=re.I)
>>> word = "HIPAA and ERP(2.0)"
>>> r.findall(word)
['HIPAA']

测试4

>>> keywords = ["HIPAA", "ERP(2.0)"]
>>> r = re.compile('|'.join([r'\b%s\b' % re.escape(w) for w in keywords]), flags=re.I)
>>> word = r"HIPAASTOL and ERP(2.0)"
>>> r.findall(word)
[]

测试5

>>> keywords = ["HIPAA", "ERP(2.0)"]
>>> r = re.compile('|'.join([re.escape(w) for w in keywords]), flags=re.I)
>>> word = r"HIPAASTOL and ERP(2.0)"
>>> r.findall(word)
['HIPAA', 'ERP(2.0)']

提前感谢:)


Tags: and字符串inreforerp关键字word
2条回答

这很有效

keywords = ["HIPAA", "ERP(2.0)"]
r = re.compile('|'.join([re.escape(w) for w in keywords]), flags=re.I)
word = r"HIPAA and ERP(2.0)"
r.findall(word)

输出

['HIPAA', 'ERP(2.0)']
  1. 必须转义特殊字符
  2. 根据定义,单词边界\b是一个与。。。单词字符\w[a-zA-z0-9_]与非单词字符\W[a-zA-z0-9_]之间的边界

在您的例子中,您有regex:\bHIPAA\b|\bERP(2.0)\b

前一个\bHIPAA\b没有问题,但后一个\bERP(2.0)\b显示了两个错误

  1. 帕伦一家必须逃走
  2. 最后一个单词边界需要一个紧跟在结束符后面的单词字符

要转义特殊字符,必须使用re.escape函数:

re.escape(w) for w in keywords

要在不使用\b的情况下检测单词边界,必须声明关键字前后没有单词字符,因此必须使用lookaround:

  • (?<!\w)在关键字“负向后看”之前,确保之前没有单词字符
  • (?!\w)在关键字后面,负向前看,确保后面没有单词字符

您的正则表达式变成:

r = re.compile('|'.join([r'(?<!\w)%s(?!\w)' % re.escape(w) for w in keywords]), flags=re.I)

Demo & explanation

相关问题 更多 >