正则表达式:如何排除多个字符组?

时间:2010-01-08 05:30:26

标签: regex

我有一组网址:

  

/产品

     

/类别

     

/客户

现在说客户名为约翰,我想帮助约翰用更短的网址到达他自己的帐户页面:

before : /customers/john
after  : /john

(假设客户名称是唯一的)

我正在尝试找出一个合适的正则表达式调度程序,以便所有客户都能拥有此功能:

/marry
/james
/tony-the-red-beard

这是我现在得到的(在PHP中):

'/^\/([^(products|categories|admin)].+)$/' => /customers/$1

这似乎不起作用。有人可以帮帮我吗?

3 个答案:

答案 0 :(得分:18)

这里你需要的是一个负向前瞻assertion。你想说的是“我希望匹配任何字符串,除了这些特殊的字符串。”正则表达式中的断言可以匹配字符串,但它不会消耗任何字符,允许这些字符与正则表达式的其余部分匹配。您可以通过在(?!)中包装模式来指定否定断言。

'/^\/(?!products|categories|admin)(.+)$/'

请注意,如果您不允许客户名称包含斜杠,则可能需要以下内容:

'/^\/(?!products|categories|admin)([^/]+)$/'

答案 1 :(得分:8)

这完全是解决问题的错误方法,但是可以在不使用负前瞻的情况下表达固定的负向前瞻。为清晰起见,额外间距:

^ (
( $ | [^/] |
  / ( $ | [^pc] |
    p ( $ | [^r] |
      r ( $ | [^o] |
        o ( $ | [^d] |
          d ( $ | [^u] |
            u ( $ | [^c] |
              c ( $ | [^t] |
                t ( $ | [^s] ))))))) |
    c ( $ | [^au] |
      a ( $ | [^t] |
        t ( $ | [^e] |
          e ( $ | [^g] |
            g ( $ | [^o] |
              o ( $ | [^r] |
                r ( $ | [^i] |
                  i ( $ | [^e] |
                    e ( $ | [^s] )))))))) |
      u ( $ | [^s] |
        s ( $ | [^t] |
          t ( $ | [^o] |
            o ( $ | [^m] |
              m ( $ | [^e] |
                e ( $ | [^r] |
                  r ( $ | [^s] ))))))))))
) .* ) $

答案 2 :(得分:0)

你试图以错误的方式使用否定的字符类。否定的字符类表示“与包含的字符不匹配”。你想说的是“如果我在这里指定的东西存在,那就不匹配”。要做到这一点,你必须更有创意。可能需要一些消极的看法。我不是100%肯定php的正则表达式引擎,但类似的东西应该有效。

/^\/(?<!(?:products|categories|admin))(.+)$/

因此,如果(?<! ... ).+products前面有categories,那么负面的后视admin说不匹配(?: ... )。那就是非捕获组{{1}}。

查看Regular Expression Advanced Syntax Reference以获取额外帮助。