Yang
Yang

Reputation: 8701

Cannot properly match and extract parameters from a string

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?

Upvotes: 1

Views: 49

Answers (3)

Ramin Omrani
Ramin Omrani

Reputation: 3761

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.

Upvotes: 1

Konsole
Konsole

Reputation: 3475

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" }

Upvotes: 0

anubhava
anubhava

Reputation: 785128

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
)

Upvotes: 1

Related Questions