字边界和小于标志

时间:2016-05-14 16:03:12

标签: python regex

我希望这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')

2 个答案:

答案 0 :(得分:2)

\b匹配单词开头或结尾处的空字符串,单词被定义为“{1}}不属于的”字母数字或下划线字符序列“。以下是Python docs的完整说明:

  

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

答案 1 :(得分:0)

将我的评论翻译成答案。

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

你可以使用这种负面的lookbehind断言:

>>> 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