2016-05-14 7 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、はい、しかし –

+1

[OK]はそれを得たnot' '主張があります。 '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 
関連する問題