正则表达式不符合预期的url

时间:2012-02-02 19:14:10

标签: php regex

我正在尝试将不同的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以支持多次相同的类别标识符,它会被解析,我希望(...)*会多次解析它而不是给我一个大的类别标识符列表。< / p>

例如,这很好用:

#^/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个类别,我被阻止,网址将无法正确解析...

有没有办法支持?

2 个答案:

答案 0 :(得分:2)

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

*使捕获组更大,但不会使位置成倍增加。

您可能希望在第二步中使用带有(/([0-9]+)-([0-9a-z\_]+))的“findall”拆分第一组

答案 1 :(得分:0)

考虑此代码以获取单个类别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
        )

)