是否有正则表达式匹配包含A但不包含B的字符串

时间:2011-11-23 10:41:04

标签: regex contains inverse

我的问题是我想用纯正则表达式检查browserstring。

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 但它完全符合错误。

3 个答案:

答案 0 :(得分:57)

使用前瞻断言来检查字符串是否包含单词。

如果你想确保字符串在某个地方包含“Android”,你可以这样做:

^(?=.*Android).*

你也可以将它们组合起来,以确保它在某个地方包含“Android”并在某个地方包含“移动”:

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

如果您想确保某个单词不在字符串中,请使用负向预测:

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

这需要单词“Android才能在字符串中,并且字符串中不允许使用”Mobile“。当开头的断言为真时,.*部分匹配完整的字符串/行

here on Regexr

答案 1 :(得分: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)

仅供参考Lookahead/lookbehind


更新使用Perl5正则表达式(可以说是最流行的味道)测试这些很好:

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

节目:

1 yes

用于OP中的给定输入

答案 2 :(得分:2)

通过正则表达式的一些实现,您可以使用负向lookbehind断言。 根据文档,只有当字符串中的当前位置没有匹配(?<!...)

时,写为...的负面后视才会匹配

这是一个Python交互式脚本,展示了如何在示例字符串中使用负向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