1

I'm sitting about 2 hours trying to extract parameters from a string. No matter how many parameters it has.

Consider this (example),

$template = "/category/(:any)/(:any)/(:any)/";
$input    = "/category/username/category-id/2";

And I would like an array of parameters to be like this,

Array (
    [0] => username
    [1] => category-id
    [2] => 2
)

So, I've started from,

$replacements = array(
    '(:any)'        =>  '.+(?=/|$)',
);

$str = '/category/(:any)/(:any)/(:any)';
$str = str_replace(array_keys($replacements), array_values($replacements), $str);

$input = '/category/username/category-id/2';

$pattern = '~^' . $str . '$~';

preg_match($pattern, $input, $matches);

print_r($matches);

// That prints Array ( [0] => /category/username/category-id/2 ) 

But now I'm stuck with proper parameter extracting. The very first that that comes to mind is to find similar values between two strings and remove them. Then remove (:any) and /.

$template = "/category/(:any)/(:any)/(:any)/";
$input    = "/category/username/category-id/2";

The problem is that, it will require a lot of extra work relying on explode().

So the question is : (take a look at the first code example): How can I properly achieve that using a regular expression, that would match and properly put parameters in $matches?

3 Answers 3

1

I believe this regex should work:

$replacements = array(
    '(:any)'        =>  '([^/]*)',
);

$template = "/category/(:any)/(:any)/(:any)/";
$input    = "/category/username/category-id/2";

$str = '/category/(:any)/(:any)/(:any)';
$str = str_replace(array_keys($replacements), array_values($replacements), $str);

$input = '/category/username/category-id/2';

$pattern = '~^' . $str . '$~';

preg_match($pattern, $input, $matches);

print_r($matches);

OUTPUT:

Array
(
    [0] => /category/username/category-id/2
    [1] => username
    [2] => category-id
    [3] => 2
)
Sign up to request clarification or add additional context in comments.

4 Comments

That returns the same Array ( [0] => /category/username/category-id/2 ), while I'd like it to be Array ( [0] => username [1] => category-id [2] => 2)
You need to use preg_match_all I believe.
Well, preg_match_all() returns almost the same: Array ( [0] => Array ( [0] => /category/username/category-id/2 ) )
@DaveJust: See full code in my answer, you just needed capturing group in your $replacements array. Output is also shown above.
1

You can use preg_split() function like this:

$pattern = "/[\/]/";
$parameters = preg_split($pattern, "/category/username/category-id/2");
array_shift($parameters);
array_shift($parameters);
var_dump($parameters);

this code splits the string into an array by delimiter /. the structure is like this:

array(5) { 
    [0]=> string(0) "" 
    [1]=> string(8) "category" 
    [2]=> string(8) "username" 
    [3]=> string(11) "category-id" 
    [4]=> string(1) "2" 
}

then by using array_shift() 2 times the result would be:

array(3) { 
    [0]=> string(8) "username" 
    [1]=> string(11) "category-id" 
    [2]=> string(1) "2" 
}

I'm using the words username,category_id,... and they could be variables too.

Comments

0

Same as @1linecode but without using regex.

$url = "http://somedomain.com/category/username/category-id/2";
$path = parse_url($url, PHP_URL_PATH);
$params = explode('/', $path);
array_shift($params);
array_shift($params);

Output:

array(3) { [0]=> string(8) "username" [1]=> string(11) "category-id" [2]=> string(1) "2" }

Comments

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.