包含方括号的搜索模式

Search pattern to include square brackets

我正在尝试在文件中搜索确切的单词。我逐行阅读文件并遍历这些行以找到确切的单词。由于 in 关键字不适合查找精确词,我使用正则表达式模式。

def findWord(w):
    return re.compile(r'\b({0})\b'.format(w), flags=re.IGNORECASE).search

这个函数的问题是它不识别方括号 [xyz]

例如

findWord('data_var_cod[0]')('Cod_Byte1 = DATA_VAR_COD[0]') 

returns None

findWord('data_var_cod')('Cod_Byte1 = DATA_VAR_COD') 

returns <_sre.SRE_Match object at 0x0000000015622288>

谁能帮我调整正则表达式模式?

那是因为[]有特殊的含义。您应该引用您要查找的字符串:

re.escape(regex)

将为您转义正则表达式。将您的代码更改为:

return re.compile(r'\b({0})\b'.format(re.escape(w)), flags=re.IGNORECASE).search
                                      ↑↑↑↑↑↑↑↑↑

您可以看到 re.quote 对您的字符串做了什么,例如:

>>> w = '[xyz]'
>>> print re.escape(w)
\[xyz\]

这是因为正则表达式引擎将方括号假定为字符 class,这是正则表达式字符,为了解决这个问题,您需要转义正则表达式字符。你可以使用 re.escape 函数:

def findWord(w):
    return re.compile(r'\b({0})\b'.format(re.escape(w)), flags=re.IGNORECASE).search

此外,作为获取所有匹配项的更 pythonic 方式,您可以使用 re.fildall() 其中 returns 匹配列表或 re.finditer 其中 returns 迭代器包含匹配对象。

但这种方式仍然不完整和有效,因为 当您使用单词边界时,您的内部单词必须包含一种类型的字符。

>>> ss = 'hello string [processing] in python.'  
>>>re.compile(r'\b({0})\b'.format(re.escape('[processing]')),flags=re.IGNORECASE).search(ss)
>>> 
>>>re.compile(r'({})'.format(re.escape('[processing]')),flags=re.IGNORECASE).search(ss).group(0)
'[processing]'

因此,如果您的单词包含 none 个单词字符,我建议删除单词边界。

但作为一种更通用的方法,您可以使用以下正则表达式,它使用 positive look around 匹配由 space 包围的单词或出现在字符串末尾或前导的单词:

r'(?: |^)({})(?=[. ]|$) '

您需要 "smart" 构建正则表达式的方法:

def findWord(w):
    if re.match(r'\w', w) and re.search(r'\w$', w):
        return re.compile(r'\b{0}\b'.format(w), flags=re.IGNORECASE).search
    if not re.match(r'\w', w) and not re.search(r'\w$', w):
        return re.compile(r'{0}'.format(w), flags=re.IGNORECASE).search
    if not re.match(r'\w', w) and re.search(r'\w$', w):
        return re.compile(r'{0}\b'.format(w), flags=re.IGNORECASE).search
    if re.match(r'\w', w) and not re.search(r'\w$', w):
        return re.compile(r'\b{0}'.format(w), flags=re.IGNORECASE).search

问题是您的一些关键字仅在开头有单词字符,而其他关键字仅在结尾处有单词字符,大多数在两端都有单词字符,而有些则没有单词字符。要有效地检查单词边界,您需要知道关键字的 start/end 处是否存在单词字符。

因此,使用 re.match(r'\w', x) 我们可以检查关键字是否以单词字符开头,如果是,则将 \b 添加到模式中,使用 re.search(r'\w$', x) 我们可以检查如果关键字以单词字符结尾。

如果您有多个关键字来检查一个字符串,您可以检查 this post of mine.