Reputation: 12244
I'm trying to match different urls to MVC actions of my controller.
Here is the current expression i'm testing:
#^/products((/([0-9]+)-([0-9a-z\_]+))*(/(index\.(html|pdf|xml|json))?)?)?$#i
When i try to match this to:
/products/22-test/25-test2
I was expecting to get (via preg_match_all) the following results:
array(5) {
[0]=>
string(26) "/products/22-test/25-test2"
[1]=>
string(17) "/22-test"
[2]=>
string(2) "22"
[3]=>
string(5) "test"
[4]=>
string(17) "/25-test"
[5]=>
string(2) "25"
[6]=>
string(5) "test2"
}
But instead i get
array(5) {
[0]=>
string(26) "/products/22-test/25-test2"
[1]=>
string(17) "/22-test/25-test2"
[2]=>
string(9) "/25-test2"
[3]=>
string(2) "25"
[4]=>
string(5) "test2"
}
UPDATE
The problem is that i'm not getting the category list translated into individual elements just so that i make my problem as clear as possible...
I'm using (/([0-9]+)-([0-9a-z\_]+))*
in an attempt to transform as many category identifiers into a parsed item. Thats why i used (...)*
, it should allow any number of categories to be matches and should match each of them no?
UPDATE 2
It seems that if i update the regexp to support many times the same category identifier, it gets parsed, i was hoping that (...)*
would parse it many times instead of giving me one big list of category identifiers.
For example, this works fine:
#^/products((/([0-9]+)-([0-9a-z\_]+))?(/([0-9]+)-([0-9a-z\_]+))?(/([0-9]+)-([0-9a-z\_]+))?(/([0-9]+)-([0-9a-z\_]+))?(/([0-9]+)-([0-9a-z\_]+))?(/(index\.(html|pdf|xml|json))?)?)?$#i
But forces me to repeat the category selector MANY times. So if i have a client that decides to put more than X categories in his catalog, i'm blocked and the urls won't resolve correctly...
Is there any way to support that?
Upvotes: 0
Views: 110
Reputation: 786349
Consider this code to get individual categories id and name:
$str = '/products/22-test/25-test2';
if (stripos($str, "/products/") !== false &&
preg_match_all('#(/(\d+)-([a-z\d_-]+))#i', $str, $m))
print_r($m);
OUTPUT:
Array
(
[0] => Array
(
[0] => /22-test
[1] => /25-test2
)
[1] => Array
(
[0] => 22
[1] => 25
)
[2] => Array
(
[0] => test
[1] => test2
)
)
Upvotes: 0
Reputation: 77505
The result is a positional result. I.e. Position 1 captures the first ()
, position 2 captures the second set of ()
.
A *
makes the capture group larger, but doesn't multiply the positions.
You might want to just split the first group using a "findall" with (/([0-9]+)-([0-9a-z\_]+))
in a second step.
Upvotes: 2