2011-11-23 9 views
22

私の問題は、純正の正規表現でブラウザ文字列をチェックしたいのです。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 が、それは正確に間違って一致します。

+2

どのような言語、正規表現の味? http://www.regular-expressions.info/tools.html – sehe

+0

それはそう簡単ではありません:[http://stackoverflow.com/q/8186424/241506][1] [1]: http://stackoverflow.com/q/8186424/241506 – VMykyt

+0

'(?:[^])*?'で何を表現したいですか? – stema

答えて

2

私は正規表現flaviourに応じて、言っ

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

は、あなたが

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

またはFYIさえ

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

が見ることを組み合わせることができ、最大それを破るだろうLookahead/lookbehind


更新は、テスト済みのPerl5正規表現の風味(ほぼ間違いなく最も人気のある味)と、これらの罰金:

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

ショー:OPで与えられた入力用

1 yes 

+0

これはPerl5互換のregexen – sehe

2

付き正規表現のいくつかの実装では、負のlookbehindアサーションを使用できます。ドキュメント毎の は、文字列内の現在位置が...

の一致が先行されていない場合にのみ(?<!...)マッチとして書かれた負の後読みはここにあなたのサンプル文字列を否定後読みを使う方法を示す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 
37

文字列に単語が含まれているかどうかを確認するために、先読みアサーションを使用します。

あなたは、文字列は、いくつかの場所での「アンドロイド」が含まれていることを保証したい場合は、このようにそれを行うことができます。

^(?=.*Android).* 

ます。また、それは、いくつかの場所で「アンドロイド」が含まれていることを確認するために、それらを組み合わせることができますそして、いくつかの場所で「モバイル」:

^(?=.*Android)(?=.*Mobile).* 

あなたは、特定の単語が先に負の外観を使用し、文字列になっていないことを確認したい場合は、次の

^(?=.*Android)(?!.*Mobile).* 

これは、文字列に "Android"という単語が必要で、文字列に "Mobile"という単語は使用できません。 .*部分は、先頭のアサーションが真のときに完全な文字列/行と一致します。

を参照してください。here on Regexr

+0

+1で最も簡単な純正正規表現のアプローチでテストされましたが、 '^(?=。* Android)(?!。* Mobile)。*'と書くとよいでしょう。そうでなければ、先読みはすべての位置で、または両方が成功するまで適用されます。肯定的な先取りはいつでもどこでも最初から失敗するので、あなたの正規表現は期待通りに機能しますが、否定的な先読みだけがあればどうでしょうか? –

+0

@ AlanMoore提案のおかげで、私はそれを使用して私の答えを編集しました。 – stema