Подтвердить что ты не робот

Существует ли регулярное выражение для соответствия строке, содержащей 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 но он точно соответствует ошибкам.

4b9b3361

Ответ 1

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

Если вы хотите убедиться, что строка содержит "Android" в каком-то месте, вы можете сделать это следующим образом:

^(?=.*Android).*

Вы также можете комбинировать их, чтобы убедиться, что он содержит "Android" в каком-то месте И "Мобильный" в каком-либо месте:

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

Если вы хотите убедиться, что определенное слово НЕ в строке, используйте негативный прогноз вперед:

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

Для этого потребуется слово "Android" в строке, а слово "Mobile" в строке не допускается. Часть .* соответствует полной строке/строке, когда утверждения в начале являются истинными.

Смотрите здесь, в Regexr

Ответ 2

Я бы просто сломал его

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)

FYI см. Lookahead/lookbehind


Обновление Протестировано с помощью аромата Perge5 regex (возможно, самый популярный вкус):

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

Показывает:

1 yes

для данного входа в OP

Ответ 3

С некоторыми реализациями регулярных выражений вы можете использовать отрицательное утверждение lookbehind. В документах отрицательный lookbehind, записанный как (?<!...), соответствует только если текущей позиции в строке не предшествует совпадение для ...

Здесь Python interactive script показывает, как использовать отрицательный lookbehind с вашими примерами строк:

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