正则表达式与预期的url不匹配


Regular expression not matching url as expected

我正在尝试将不同的url与控制器的MVC操作相匹配。

这是我正在测试的当前表达式:

#^/products((/([0-9]+)-([0-9a-z'_]+))*(/(index'.(html|pdf|xml|json))?)?)?$#i

当我尝试将其与匹配时

/products/22-test/25-test2

我希望(通过preg_match_all)得到以下结果:

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

但我得到了

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

更新

问题是,我没有把类别列表翻译成单独的元素,只是为了让我的问题尽可能清楚。。。

我使用(/([0-9]+)-([0-9a-z'_]+))*来尝试将尽可能多的类别标识符转换为解析的项目。这就是我使用(...)*的原因,它应该允许任何数量的类别匹配,并且应该匹配每个类别?

更新2

似乎如果我更新regexp以支持多次相同的类别标识符,它就会被解析,我希望(...)*会多次解析它,而不是给我一个大的类别标识符列表。

例如,这很好:

#^/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

但迫使我重复类别选择器很多次。因此,如果我有一个客户决定在他的目录中放入超过X个类别,我会被阻止,URL不会正确解析。。。

有什么办法支持这一点吗?

结果是位置结果。即位置1捕获第一个(),位置2捕获第二组()

*使捕获组变大,但不会使位置相乘。

您可能只想在第二步中使用带有(/([0-9]+)-([0-9a-z'_]+))的"findall"来拆分第一组。

考虑此代码以获得单个类别id和名称:

$str = '/products/22-test/25-test2';
if (stripos($str, "/products/") !== false &&
    preg_match_all('#(/('d+)-([a-z'd_-]+))#i', $str, $m))
   print_r($m);

输出:

Array
(
    [0] => Array
        (
            [0] => /22-test
            [1] => /25-test2
        )
    [1] => Array
        (
            [0] => 22
            [1] => 25
        )
    [2] => Array
        (
            [0] => test
            [1] => test2
        )
)