0

I'm using the following code to split incoming requests:

    /*
     *   Create global $GET from our cool URL's
     */
    preg_match_all('/[\/|\?|\&]([a-zA-Z\_0-9]+)([\/|=]([0-9]+)){0,1}/', $_SERVER['REQUEST_URI'], $parts, PREG_PATTERN_ORDER);
    if( count($parts[1]) >= 1 && count($parts[3]) >= 1)
        $GET = array_combine($parts[1], $parts[3]);

URL's like "/cat/2/post/345/answer/post" is divided into:

cat  => 2
post => 345
answer => 
post => 

is it possible to change this regex to allow for urls like: /post/345-title-goes-here/ and make it into:

post => 345-title-goes-here

becasue right now it only works if the argument is strictly 0-9 with no other characters. and even that was a real problem for me. any suggestions? :)

1
  • I've once again revisited this one, since the old one didn't seem to support single digit values. This is what I use now: #[/?&]([\w.()-]+)([/=](\d[\w.()-]+|\d))?# Commented May 18, 2015 at 2:22

2 Answers 2

1

I'd use a more concise one:

#[/?&](\w+)([/=](\d[\w-]+))?#

so the preg_match_all becomes:

preg_match_all('#[/?&](\w+)([/=](\d[\w-]+))?#', $_SERVER['REQUEST_URI'], $parts, PREG_PATTERN_ORDER);

Update according to comment:

#[/?&]([\w.()-]+)([/=](\d[\w.()-]+))?#

You can add every character you want within the character class.

Sign up to request clarification or add additional context in comments.

6 Comments

neat short version , but it makes a url like /registrera/123-hejsan/doh/eller into [registrera] => 123-hejsan , [doh] => eller instead of [doh] => , [eller] => what i mean is that for it to count as value, i want it to start with 0-9.
Nice! It sure is short and tidy -evident that you know you'r regex well! Would it be totally ruined if I asked you for supporting signs . - _ ( ) anywhere in both key & value? Only real diffrence I want for values is that it should start with a digit, otherwise, the more URL friendly characters that can be supported on both key&value the better.
@ChristofferBubach: Of course, you can add any character you want. See my edit.
Hi, this was a while ago and I've been happily using this version on my sites: '#[/?&]([\w-.]+)([/=](\d[\w-.]+))?#' (not sure anymore how this one differs from your updated one above) problem is that this code along with every other version suggested here all fails if I get a URL with "/part/part/" which I discovered due to a relocation error. It should present this as two distinct keys, but only the first one is shown in the array. Any ideas how to solve this?
Seems like my issue here was that PHP arrays can't hold non-unique keys, so array_combine would simply ignore one of them.
|
1

Sure, instead of:

'/[\/|\?|\&]([a-zA-Z\_0-9]+)([\/|=]([0-9]+)){0,1}/'

try:

'/[\/|\?|\&]([a-zA-Z\_0-9]+)([\/|=]([0-9]+[a-zA-Z_-]*)){0,1}/'

I just added the extra characters after the 0-9 in an optional (0 or more) set.

3 Comments

Doesn't this require that all parameters have a value? For example: /forum/5-general-talk/thread/45-hi-there/post/answer/ would result in all right until "post => answer" instead of "post =>" and "answer =>" ?
The regex need to somehow check that the following string consists of 0-9 then a "-" sign and then any other A-Z,a-z,- after that. Otherwise if it starts with a-z consider it a new parameter/variable.
Damn I spoke too soon, worked great! Got my hand on this from another buddy, seems to do even more, allows - in key-name for example. '/[\/|\?|\&]([a-zA-Z\-_0-9]+)([\/|=]([0-9]+\-[a-zA-Z()\.\-_0-9]+|[0-9]+)){0,1}/'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.