2016-05-14 53 views
0

我希望这3个断言能够通过,正则表达式使用了什么错误?字边界和小于符号

最后一个断言失败。在开始或一个字的结束和字

import re 

def line_has_word(line, word): 
    expr = re.compile(r'\b' + re.escape(word)) 
    return expr.search(line) is not None 

assert line_has_word('foo', 'foo') 
assert not line_has_word('zfoo', 'foo') 
assert line_has_word('<foo', '<foo') 
+1

@anubhava,是的,但有一个'断言not' –

+1

确定了它。尝试:'expr = re.compile(r'(^ | \ s)'+ re.escape(word))' – anubhava

+0

@anubhava,作品,谢谢! (我仍然试图理解你的正则表达式) –

回答

2

\b匹配到空字符串被定义为“字母数字的序列或下划线字符”,这<不的一部分。这里有从Python docs的完整描述:

匹配空字符串,但只匹配一个字的开头或结尾。一个单词被定义为一个字母数字或下划线字符序列,因此单词的末尾用空格或非字母数字,非下划线字符表示。请注意,在形式上,\ b被定义为\ w和\ w字符之间的边界(反之亦然),或\ w和字符串的开始/结尾之间的边界,所以被认为是字母数字的精确字符集取决于在UNICODE和LOCALE标志的值上。例如,r'\ bfoo \ b'匹配'foo','foo。','(foo)','bar foo baz',但不匹配'foobar'或'foo3'。在字符范围内,\ b代表退格字符,以便与Python的字符串文字兼容。

0

将我的评论翻译成答案。

问题是您在搜索词之前使用\b(词边界)。 如果搜索词的第一个字符是非单词字符,这将会失败。

您可以使用它代替负向后断言:

>>> def line_has_word(line, word): 
...  expr = re.compile(r'(?<!\w)' + re.escape(word)) 
...  return expr.search(line) is not None 
... 

(?<!\w)为负向后断言,这意味着从搜索词前面的位置没有一个字字符。

测试:

>>> print line_has_word('<foo', '<foo') 
True 
>>> print line_has_word('zfoo', 'foo') 
False 
>>> print line_has_word('bar,foo', 'foo') 
True 
>>> print line_has_word('foo', 'foo') 
True