常规快递:如何排除多个字符组?

Sha*_*awn 10 regex

我有一组网址:

/产品

/类别

/顾客

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

before : /customers/john
after  : /john
Run Code Online (Sandbox Code Playgroud)

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

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

/marry
/james
/tony-the-red-beard
Run Code Online (Sandbox Code Playgroud)

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

'/^\/([^(products|categories|admin)].+)$/' => /customers/$1
Run Code Online (Sandbox Code Playgroud)

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

Bri*_*ell 18

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

'/^\/(?!products|categories|admin)(.+)$/'
Run Code Online (Sandbox Code Playgroud)

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

'/^\/(?!products|categories|admin)([^/]+)$/'
Run Code Online (Sandbox Code Playgroud)


eph*_*ent 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] ))))))))))
) .* ) $
Run Code Online (Sandbox Code Playgroud)

  • 只是为了好玩,真的,因为其他人已经发布了正确答案. (6认同)
  • 哇.我不确定我是否应该留下深刻印象或不安.是的,有可能在正则表达式中做负面预测,即使它们没有语法糖,就像可以匹配整个范围的字符而没有字符类一样.我不确定你为什么要写`(a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | T | U | v | W | X | Y | Z | A | B | C | d | E | F | G | H | I |Ĵ| K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z)`而不是`[a-zA-Z]`,同样我也不确定为什么你要避免负面的先行断言? (?!)`. (3认同)
  • @Brian Campbell:不管你信不信,有些正则表达式风格不支持前瞻。对于那些人来说,这是唯一的方法。看起来很可怕,但如果一切都失败了……+1 (3认同)