我有一组网址:
/产品
/类别
/客户
现在说客户名为约翰,我想帮助约翰用更短的网址到达他自己的帐户页面:
before : /customers/john
after : /john
(假设客户名称是唯一的)
我正在尝试找出一个合适的正则表达式调度程序,以便所有客户都能拥有此功能:
/marry
/james
/tony-the-red-beard
这是我现在得到的(在PHP中):
'/^\/([^(products|categories|admin)].+)$/' => /customers/$1
这似乎不起作用。有人可以帮帮我吗?
答案 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}}。