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

问题描述 投票:0回答:3

我的问题是我想用纯正则表达式检查浏览器字符串。

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
但它完全匹配错误。

regex contains inverse
3个回答
97
投票

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

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

^(?=.*Android).*

您也可以将它们组合起来,以确保它在某些地方包含“Android”而在某些地方包含“Mobile”:

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

如果要确保某个单词不在字符串中,请使用否定的前瞻:

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

这将要求“Android”一词出现在字符串中,并且字符串中不允许出现“Mobile”一词。当开头的断言为真时,

.*
部分匹配然后是完整的字符串/行。

在 Regexr 上看到它


3
投票

通过一些正则表达式的实现,你可以使用否定的回顾断言。 根据文档,仅当字符串中的当前位置前面没有匹配

(?<!...)
 时,写为 
...

的负向后视才匹配

这里是一个 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

1
投票

我只是打破它

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)

仅供参考前瞻/后视


Update 使用 Perl5 regex flavor(可以说是最受欢迎的 flavor)测试这些很好:

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

演出:

1 yes

对于 OP 中的给定输入

© www.soinside.com 2019 - 2024. All rights reserved.