Регулярное выражение агента пользователя - PullRequest
5 голосов
/ 24 июня 2011

Я почти стесняюсь спросить, но только почти.Кажется, у меня уже есть выражение, которое работает, но кажется, что оно работает только в различных инструментах регулярных выражений, таких как Regulator или онлайн-инструменты.Оказавшись в моем коде на C #, он не может попасть туда, куда должен.

Поэтому проблема в том, что мне нужно регулярное выражение для попадания в строки агента пользователя, содержащие «android», «iphone» или «ipod», но нете, которые также содержат «оперу».Достаточно просто, верно?

Пока у меня есть это:

^(?=.*?\b(android|iphone|ipod)\b)(?!opera).*$

Я использую следующие опции

RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase | RegexOptions.Singleline

Пожалуйста, скажите мне, где я получилэто неправильно.

Вот несколько строк пользовательских агентов.Выражение должно запускаться первым и последним, игнорируя два в середине:

Mozilla/5.0+(Linux;+U;+Android+2.2;+nb-no;+Nexus+One+Build/FRF91)+AppleWebKit/533.1+(KHTML,+like Gecko)+Version/4.0+Mobile+Safari/533.1
Opera/9.80 (Android; Linux; Opera Mobi/ADR-1012221546; U; pl) Presto/2.7.60 Version/10.5
Opera/9.80 (J2ME/iPhone;Opera Mini/5.0.019802/886; U; ja)Presto/2.4.15
Mozila/5.0 (iPod; U; CPU like Mac OS X; en) AppleWebKit/420.1 (KHTML, like Geckto) Version/3.0 Mobile/3A101a Safari/419.3

Спасибо

Ответы [ 4 ]

5 голосов
/ 24 июня 2011

Вы помните, чтобы добавить "@" перед строкой шаблона?Если нет, то "\ b" будет интерпретироваться как возврат.

Также, как некоторые говорят, вы не проверяете Opera нигде, кроме начала строки, это специально?Я бы, вероятно, использовал этот синтаксис вместо:
@"^(?!opera)(?=.*\b(android|iphone|ipod)\b).*$"

1 голос
/ 24 июня 2011

Негативные прогнозы хитры .Короче говоря, вы отклоняете только те строки, которые не содержат Opera в начале строки (исправлено, спасибо @stema).Честно говоря, чтобы избежать путаницы, часто связанной с прогнозированием, вы можете разбить ее на две части:

Вариант 1:

Используйте регулярное выражение безвзгляд вперед, плюс String.Contains()

Regex myRegex = "(? i) (android | iphone | ipod)";// без учета регистра

bool isUserStringNonOperaMobile = myRegex.isMatch (userString) &&! userString.ToLower (). Contains ("opera");

Опция 2:

Используйте два регулярных выражения

Regex myRegex = "(? I) (android | iphone | ipod)";// без учета регистра

Regex myOtherRegex = "(? i) opera";// без учета регистра

bool isUserStringNonOperaMobile = myRegex.isMatch (userString) &&! myOtherRegex.isMatch (userString);

Да, они могут быть несколько менее эффективными, но их можно пренебречь,а то, что вы теряете в эффективности, вы получаете в удобочитаемости и удобстве обслуживания.

1 голос
/ 24 июня 2011

Вы проверяете opera только в самом начале строки.Это предназначено?

Каждый взгляд вперед пытается соответствовать с самого начала.Вы привязываете его к ^, и тогда у вас есть только opera, никакие другие символы ранее не допускаются.

Попробуйте

^(?=.*?\b(android|iphone|ipod)\b)(?!.*opera).*$

, чтобы найти opera где-нибудь в строке.

0 голосов
/ 24 июня 2011

Я не знаком с c #, но вы уверены, что он поддерживает конструкцию ?!?

...