开发者

regular express : how to exclude multiple character groups?

开发者 https://www.devze.com 2022-12-16 06:01 出处:网络
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:

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消