理解为什么负向前瞻不起作用

时间:2016-07-01 11:49:44

标签: regex regex-lookarounds

我们说我有这个网址:

  

https://www.google.com/search?q=test&tbm=isch&randomParameters=123

我希望匹配Google的搜索网址,但不包含:

  

TBM = isch

     

TBM =消息

     

参数1 = 432

我尝试过这种模式:

^http(s):\/\/www.google.(.*)\/(search|webhp)\?(?![\s]+(tbm=isch|tbm=news|param1=432))

但它没有工作(如仍然匹配),样本网址

3 个答案:

答案 0 :(得分:3)

您可以使用:

^                         # anchor it to the beginning
https?://                 # http or https
(?:
    (?!tbm=(?:isch|news)) # first neg. lookahead
    (?!param1=432)        # second
    \S                    # anything but whitespace
)+
$                         # THE END

请参阅a demo on regex101.com 可能会有针对您的特定编程语言的内置方法,如urlparse()

答案 1 :(得分:2)

你的正则表达式应该是

^https:\/\/www.google.([^\/]*)\/(search|webhp)\?(?!.*(tbm\=isch|tbm\=news|param1\=432)).*$

example

问题在于您尝试使用\s*代替.*进行预测,这将匹配任意数量的字符。

同样www.google.(.*)会导致大量回溯导致性能问题,因此我将其替换为www.google.([^\/]*)

修改

我想知道你为什么使用正则表达式而不是简单的indexof或类似的方法来自你正在使用的语言。这里有什么特殊的用法吗?

答案 2 :(得分:1)

您应该将[\s]+更改为.*?[\S]*?,您的正则表达式才有效。要匹配整个网址,如果符合条件,您可以在最后添加另一个[\ S] *:

^http(s):\/\/www.google.([\w\.]*)\/(search|webhp)\?(?![\S]*?(tbm=isch|tbm=news|param1=432))[\S]*