假设我想匹配短语Sortes\index[persons]{Sortes}在短语test Sortes\index[persons]{Sortes} text中的存在。
使用python re我可以这样做:
>>> search = re.escape('Sortes\index[persons]{Sortes}')
>>> match = 'test Sortes\index[persons]{Sortes} text'
>>> re.search(search, match)
<_sre.SRE_Match object; span=(5, 34), match='Sortes\\index[persons]{Sortes}'>这是可行的,但我希望避免使用搜索模式Sortes,以便在短语test Sortes\index[persons]{Sortes} text上给出一个积极的结果。
>>> re.search(re.escape('Sortes'), match)
<_sre.SRE_Match object; span=(5, 11), match='Sortes'>所以我使用\b模式,如下所示:
search = r'\b' + re.escape('Sortes\index[persons]{Sortes}') + r'\b'
match = 'test Sortes\index[persons]{Sortes} text'
re.search(search, match)现在,我没有找到匹配的。
如果搜索模式不包含任何字符[]{},则可以工作。例如:
>>> re.search(r'\b' + re.escape('Sortes\index') + r'\b', 'test Sortes\index test')
<_sre.SRE_Match object; span=(5, 17), match='Sortes\\index'>另外,如果我移除最后的r'\b',它也能工作:
re.search(r'\b' + re.escape('Sortes\index[persons]{Sortes}'), 'test Sortes\index[persons]{Sortes} test')
<_sre.SRE_Match object; span=(5, 34), match='Sortes\\index[persons]{Sortes}'>此外,文档还提到了\b
注意,在形式上,\b被定义为a \w和a \W字符之间的边界(反之亦然),或者是\w和字符串的开头/结尾之间的边界。
因此,我尝试用(\W|$)替换最终的(\W|$)
>>> re.search(r'\b' + re.escape('Sortes\index[persons]{Sortes}') + '(\W|$)', 'test Sortes\index[persons]{Sortes} test')
<_sre.SRE_Match object; span=(5, 35), match='Sortes\\index[persons]{Sortes} '>瞧,它起作用了!这里发生什么事情?我遗漏了什么?
发布于 2017-07-17 13:37:43
查看单词边界匹配的内容:
单词边界可以出现在以下三个位置之一:
在您的模式中,}\b只匹配}后面的单词char (字母、数字或_)。
使用(\W|$)时,需要显式地使用非字或字符串的结尾。
一种解决方案是自适应字界
re.search(r'(?:(?!\w)|\b(?=\w)){}(?:(?<=\w)\b|(?<!\w))'.format(re.escape('Sortes\index[persons]{Sortes}')), 'test Sortes\index[persons]{Sortes} test')或相当于:
re.search(r'(?!\B\w){}(?<!\w\B)'.format(re.escape('Sortes\index[persons]{Sortes}')), 'test Sortes\index[persons]{Sortes} test')在这里,使用了自适应的动态单词边界,这意味着:
(?:(?!\w)|\b(?=\w)) (等于(?!\B\w)) -一个左边框,如果下一个字符是一个单词字符,则确保当前位置在单词边界,或者如果下一个字符不是一个单词字符,则不应用上下文限制(注意,如果您想要禁止在左边的一个单词字符,如果下一个字符不是字符,则需要使用(?:\B(?!\w)|\b(?=\w)) )。(?:(?<=\w)\b|(?<!\w)) (等于(?<!\w\B)) --一个右边框,如果前一个字符是一个单词字符,则确保当前位置在单词边界,或者如果前一个字符不是一个单词字符,则不应用上下文限制(注意,如果您想不允许在右边立即使用一个单词char,如果前面的字符不是一个字符,则需要使用(?:(?<=\w)\b|\B(?<!\w)) )。在这些情况下,您还可以考虑使用基于负面查找的无歧义的单词边界:
re.search(r'(?<!\w){}(?!\w)'.format(re.escape('Sortes\index[persons]{Sortes}')), 'test Sortes\index[persons]{Sortes} test')在这里,如果当前位置左侧有一个单词char,则(?<!\w)负查找将导致匹配失败,如果当前位置右侧有一个单词char,则(?!\w)负查找将导致匹配失败。
与明确的单词边界相比,选择哪一个?自适应字词边界更为宽松,因为后者假定匹配的两端必须没有单词字符,而前者允许在任何上下文中匹配、引导和尾随非单词字符。
注意:进一步定制这些查找模式很容易(例如,只有在模式周围有字母的情况下,才能使匹配失败,使用[^\W\d_]而不是\w,或者如果只允许在空格周围匹配,则使用空白边界 (?<!\S) / (?!\S)查找边界)。
发布于 2017-07-17 13:45:47
我想这就是你遇到的情况:
\b位于\w和\W的边界上,但在示例中这是行不通的。'{Sortes}\b'是\W和\W之间的边界,因为'}'与\w的普通集合[a-zA-Z0-9_]不匹配。
https://stackoverflow.com/questions/45145626
复制相似问题