web-dev-qa-db-ja.com

Aを含むがBを含まない文字列に一致する正規表現はありますか

私の問題は、純粋な正規表現でブラウザ文字列をチェックしたいということです。

_Mozilla/5.0 (Linux; U; Android 3.0; en-us; Xoom Build/HRI39) AppleWebKit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13
_

->一致する必要があります

_Mozilla/5.0 (Linux; U; Android 2.2.1; en-us; Nexus One Build/FRG83) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1 
_

一致してはいけません

私が試した解決策は:/?((?<=Android)(?:[^])*?(?=Mobile))/iですが、完全に間違っています。

36
user1061688

解散するだけ

if ((m/Android/i) && (m/Safari/i) && !(m/Mobile Safari/i))

とはいえ、正規表現の好みに応じて、それを組み合わせることができます

if ((m/Android/i) && (m/(?<!Mobile )Safari/i))

あるいは

if (m/Android.*(?<!Mobile )Safari/i)

参考までに Lookahead/lookbehind


UpdatePerl5正規表現フレーバー(おそらく最もポピュラーなフレーバー)でこれらをテストしました:

Perl -ne 'print "$. yes\n" if m/Android.*(?<!Mobile )Safari/i'

ショー:

1 yes

oPの指定された入力に対して

2
sehe

正規表現の一部の実装では、ネガティブな後読みアサーションを使用できます。ドキュメントによれば、(?<!...)として記述された否定的な後読みは、文字列内の現在の位置の前に...の一致がない場合にのみ一致します

Pythonインタラクティブスクリプトで、サンプル文字列でネガティブルックビハインドを使用する方法を示します。

>>> s = "Mozilla/5.0 (Linux; U; Android 3.0; en-us; Xoom Build/HRI39) AppleWebKit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13"
>>> bool(re.search(r'Android.*(?<! Mobile) Safari', s))
True

>>> t = "Mozilla/5.0 (Linux; U; Android 2.2.1; en-us; Nexus One Build/FRG83) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1"
>>> bool(re.search(r'Android.*(?<! Mobile) Safari', t))
False
2