regular express : how to exclude multiple character groups?
I have a set of urls :
/products
/categories
/customers
Now say a customers is named john, and I want to help john to reach his own account page with a shorter url:
before : /customers/john
after : /john
(suppose customer names are unique)
I'm trying to figure out a proper regex dispatcher so all customers can have this feature :
/marry
/james
/tony-the-red-beard
here is what I got now(in PHP) :
'/^\/([^(products|categories|admin)].+)$/' =>开发者_如何学编程; /customers/$1
This doesn't seem to work. Anybody can help me?
What you need here is a negative lookahead assertion. What you want to say is "I want to match any string of characters, except for these particular strings." An assertion in a regex can match against a string, but it doesn't consume any characters, allowing those character to be matched by the rest of your regex. You can specify a negative assertion by wrapping a pattern in (?!
and )
.
'/^\/(?!products|categories|admin)(.+)$/'
Note that you might want the following instead, if you don't allow customers names to include slashes:
'/^\/(?!products|categories|admin)([^/]+)$/'
This is entirely the wrong way to go about solving the problem, but it is possible to express fixed negative lookaheads without using negative lookaheads. Extra spacing for clarity:
^ (
( $ | [^/] |
/ ( $ | [^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] ))))))))))
) .* ) $
You're trying to use a negated character class the wrong way. A negated character class says 'do not match the contained characters'. What you are wanting to say is 'do not match if this stuff I specified here exists'. To do that you have to a bit more creative. Probably need some negative lookbehind. I'm not 100% sure about php's regex engine but something similar to this should work.
/^\/(?<!(?:products|categories|admin))(.+)$/
so, negative lookbehind (?<! ... )
saying don't match the .+
if products
or categories
or admin
precede it. Then that is in a non-capturing group (?: ... )
.
Check out Regular Expression Advanced Syntax Reference for extra help.
精彩评论