如何在正则表达式中包含或排除某些特定模式


How to include or exclude some specific patterns in regex?

我正在尝试匹配URL的部分。首先,我试图得到一个匹配只有这样的东西:

http://Stackoverflow.com/questions/blah/balh.blah  
http://www.stackoverflow.com/questions/blah/balh.blah  
stackoverflow.com/questions/blah/balh.blah  
www.stackoverflow.com/  

但我想使用其他协议,如httpsftp以及。我自己写了这样的东西,一点也不好:

((http:'/'/|https:'/'/|ftp:'/'/)*)((www.)*)([a-z]+).([a-z]{2,3})('/)*

这个正则表达式有很多问题,我需要弄清楚如何修复它。
首先,我如何指定例如只有httphttps有效,而不是htttphazzzzt或其他?
更准确地说:

  1. 我们如何指定一个特定的词被包括或排除?

现在很清楚的是,(http)不被视为一个单词,它只是一个字符的类集,所以任何只有这些字母中的一个的单词都得到匹配。我读过关于'b作为单词边界的文章,但似乎'bhttp'b实际上并不意味着将http视为单个单词而不是一组字符!

对于www部分,匹配wwwwww或任何其他数量的w s!无论我输入什么,我总是得到匹配!我使用http://regex101.com/来测试正则表达式。

侯赛因,你的问题有几个要点和问题。

。如何包括或排除一些特定的模式在正则表达式?

有很多技巧。对于简单的模式,您可以指定您想要的,或者指定您不想要的,或者使用负字符类或负查找。对于更复杂的模式,最好从匹配(或替换)模式开始,除了s1、s2、s3等情况

B。如何包含或排除特定的单词?

一般来说,为了确定一个特定的单词属于或不属于一个字符串,如果你不知道它的位置,你在字符串的开头做一个提前查找(或负提前查找):

^(?=.*?MyWord)   # makes sure the word is there

^(?!.*?MyWord)   # makes sure the word is not there

C。What is clear now, is that (http) is not treated like a word, it is just a class set of characters, so any word that has only one of those letters gets a match

这是不对的。(http)只匹配http。例如,它将不匹配ptth。也许您正在考虑[http],这将是一个字符类,允许字符h, t和p匹配一次(并且效率低下,因为[pth]会这样做)

D。如何匹配URL的各个部分

有很多解决方案,但今天我建议不要重新发明轮子。我可以建议使用RegexBuddy库中的正则表达式来实现这个目的吗?这是
(?i)'b((?#protocol)https?|ftp)://((?#domain)[-A-Z0-9.]+)((?#file)/[-A-Z0-9+&@#/%=~_|!:,.;]*)?((?#parameters)'?[A-Z0-9+&@#/%=~_|!:,.;]*)?

下面是逐个标记的解释(我在开头添加了不区分大小写的(?i)修饰符)

  • 断言在字边界处的位置(位置之前或之后-但不是同时-由Unicode字母,数字或下划线)'b
  • 匹配下面的正则表达式并将其匹配捕获到反向引用编号1 ((?#protocol)https?|ftp)
    • 匹配这个选项(只有当这个选项失败时才尝试下一个选项)(?#protocol)https?
      • 注释:协议(?#protocol)
      • 逐字匹配字符串" http "(不区分大小写)http
      • 匹配字符"s"(不区分大小写)s?
        • 在0到1次之间,尽可能多的次数,根据需要回馈(贪婪)?
    • 或者匹配此选项(如果此选项不匹配,则整个组失败)ftp
      • 逐字匹配字符串" ftp "(不区分大小写)ftp
  • 匹配字符串"://"字面意思://
  • 匹配下面的正则表达式并将其匹配捕获到反向引用号2 ((?#domain)[-A-Z0-9.]+)
    • 注释:域(?#domain)
    • 匹配[-A-Z0-9.]+下面列表中的单个字符
      • 在一次到无限次之间,尽可能多的次数,根据需要回馈(贪婪)+
      • 文字字符" - " -
      • 在" A "到" Z "之间的字符(不区分大小写)A-Z
      • 0 ~ 9之间的字符0-9
      • 文字字符"。".
  • 匹配下面的正则表达式并将其匹配捕获到反向引用编号3 ((?#file)/[-A-Z0-9+&@#/%=~_|!:,.;]*)?
    • 在0到1次之间,尽可能多的次数,根据需要回馈(贪婪)?
    • 注释:文件(?#file)
  • 匹配字符"/" /
  • 匹配[-A-Z0-9+&@#/%=~_|!:,.;]*下面列表中的单个字符
    • 在0到无限次之间,尽可能多的次数,根据需要回馈(贪婪)*
    • 文字字符" - " -
    • 在" A "到" Z "之间的字符(不区分大小写)A-Z
    • 0 ~ 9之间的字符0-9
    • +和单个字符从列表中" ;@#/%=~_|!:,.;" +&@#/%=~_|!:,.;
  • 匹配下面的正则表达式并将其匹配捕获到反向引用编号4 ((?#parameters)'?[A-Z0-9+&@#/%=~_|!:,.;]*)?
    • 在0到1次之间,尽可能多的次数,根据需要回馈(贪婪)?
    • 注释:参数(?#parameters)
    • 匹配字符"?"'?
    • 匹配[A-Z0-9+&@#/%=~_|!:,.;]*下面列表中的单个字符
      • 在0到无限次之间,尽可能多的次数,根据需要回馈(贪婪)*
      • 在" A "到" Z "之间的字符(不区分大小写)A-Z
      • 0 ~ 9之间的字符0-9
      • +和单个字符从列表中" ;@#/%=~_|!:,.;" +&@#/%=~_|!:,.;
  • 不认为你需要外部括号,例如下面是匹配http://或www。(确保转义句点)

    (http:'/'/|www'.)
    

    如果你使用preg_match和apache。htaccess有一点不同比如你使用一个字符来表示模式的开始和结束比如#

    $regEx = '#(http:'/'/|www'.)#';
    

    也许你可以使用PHP过滤器函数?

    if (filter_var($url, FILTER_VALIDATE_URL) !== false)
    

    FILTER_VALIDATE_URL根据RFC 2396验证url。

    http://www.php.net/manual/de/filter.filters.validate.php