1

我正在尝试 preg_match 一个由类别 slug、一个可选的子类别 slug 和一个选项项 slug 组成的 url。

它适用于所有情况,除了第 4 种情况。

$urls[0] = '/main_cat_slug';
$urls[1] = '/main_cat_slug/';
$urls[2] = '/main_cat_slug/sub_cat_slug';
$urls[3] = '/main_cat_slug/sub_cat_slug/';
$urls[4] = '/main_cat_slug/item.html';
$urls[5] = '/main_cat_slug/sub_cat_slug/item.html';

$regexp   = array();
$regexp[] = '/(?:(?<category>[\w]+)/?)';    // Find the main category (is always available)
$regexp[] = '(?:(?<subcategory>[\w]+)/?)?'; // Find an optional sub-category, is not always available
$regexp[] = '(?:(?<item>[\w]+)\.html)?';    // Find an optional item, is not always available (don't catch the extension)
$regexp   = implode('', $regexp);

foreach($urls as $index=>$url) {
preg_match("#{$regexp}#i", $url, $matches);
echo '<pre><h1>', $index, '</h1>';
echo $url, '<br />';
echo '<br />';
print_r($matches);
}

在第 4 种情况下,将找到类别,但项目为空,并且子类别获取值 op“项目”。

有人可以帮我,这样第 4 个案例只会得到一个类别和一个项目吗?

这是上面代码的输出:

0
/main_cat_slug

Array
(
    [0] => /main_cat_slug
    [category] => main_cat_slug
    [1] => main_cat_slug
)

1
/main_cat_slug/

Array
(
    [0] => /main_cat_slug/
    [category] => main_cat_slug
    [1] => main_cat_slug
)

2
/main_cat_slug/sub_cat_slug

Array
(
    [0] => /main_cat_slug/sub_cat_slug
    [category] => main_cat_slug
    [1] => main_cat_slug
    [subcategory] => sub_cat_slug
    [2] => sub_cat_slug
)

3
/main_cat_slug/sub_cat_slug/

Array
(
    [0] => /main_cat_slug/sub_cat_slug/
    [category] => main_cat_slug
    [1] => main_cat_slug
    [subcategory] => sub_cat_slug
    [2] => sub_cat_slug
)

4
/main_cat_slug/item.html

Array
(
    [0] => /main_cat_slug/item
    [category] => main_cat_slug
    [1] => main_cat_slug
    [subcategory] => item
    [2] => item
)

5
/main_cat_slug/sub_cat_slug/item.html

Array
(
    [0] => /main_cat_slug/sub_cat_slug/item.html
    [category] => main_cat_slug
    [1] => main_cat_slug
    [subcategory] => sub_cat_slug
    [2] => sub_cat_slug
    [item] => item
    [3] => item
)

亲切的问候!帕特里克

4

2 回答 2

1

描述

此正则表达式将使用以下规则挑选三种类型的数据:

  1. 始终是字符串中的/第一个字符
  2. Main_Cat 总是第一个,它跟随第一个/并一直持续到下一个/
  3. 如果第一个字符串以结尾,.html/那么这是 Main_Cat
  4. 如果第一个字符串以字符串结尾.html,然后是字符串的结尾,那么这是一个项目
  5. Sub_Cat 总是第二个,它跟随第二个/并一直持续到下一个/
  6. 如果第二个字符串以结尾,.html/那么这是一个 Sub_Cat
  7. 如果第二个字符串以字符串.html的结尾结尾,那么这是一个项目
  8. Item 类型总是有一个.html后缀
  9. /项目之后永远不会有
  10. 项目类型将始终是最后一个字段

^\/(?:(?<Main_Cat>(?![^\/\r\n]*\.html\s*$)[^\/\r\n]*)\/)?(?:(?<Sub_Cat>(?![^\/\r\n]*\.html\s*$)[^\/\r\n]*)\/)?(?:(?<Item>[^\/\r\n]*?)(?:\.html|$))?

在此处输入图像描述

如果您对单个字符串使用此表达式,则可以删除换行符\r\n。结果表达式如下所示:^\/(?<Main_Cat>[^\/]*)(?:(?:\/(?![^\/]*\.html)(?<Sub_Cat>[^\/]*))?(?:\/(?<Item>[^\/]*)\.html)?)?.*?$遵循上述相同规则。注意行尾$强制测试匹配你的整个字符串

PHP 代码示例:

源字符串

/category0.html/subcat/item.html
/item1.html
/category2.html/subcat2.html/item2.html
/category3.html/subcat3.html/
/category4.html/item4.html
/main_cat_slug5.html/
/main_cat_slug6/item6
/main_cat_slug7/sub_cat_slug7.html/
/main_cat_slug8/item8.html
/main_cat_slug9/sub_cat_slug9/item9.html

代码

<?php
$sourcestring="your source string";
preg_match_all('/^\/(?:(?<Main_Cat>(?![^\/\r\n]*\.html\s*$)[^\/\r\n]*)\/)?(?:(?<Sub_Cat>(?![^\/\r\n]*\.html\s*$)[^\/\r\n]*)\/)?(?:(?<Item>[^\/\r\n]*?)(?:\.html|$))?/imx',$sourcestring,$matches);
echo "<pre>".print_r($matches,true);
?>

火柴

$matches Array:
(
    [0] => Array
        (
            [0] => /category0.html/subcat/item.html
            [1] => /item1.html
            [2] => /category2.html/subcat2.html/item2.html
            [3] => /category3.html/subcat3.html
            [4] => /category4.html/item4.html
            [5] => /main_cat_slug5.html
            [6] => /main_cat_slug6
            [7] => /main_cat_slug7/sub_cat_slug7.html
            [8] => /main_cat_slug8/item8.html
            [9] => /main_cat_slug9/sub_cat_slug9/item9.html
        )

    [Main_Cat] => Array
        (
            [0] => category0.html
            [1] => 
            [2] => category2.html
            [3] => category3.html
            [4] => category4.html
            [5] => main_cat_slug5.html
            [6] => main_cat_slug6
            [7] => main_cat_slug7
            [8] => main_cat_slug8
            [9] => main_cat_slug9
        )

    [Sub_Cat] => Array
        (
            [0] => subcat
            [1] => 
            [2] => subcat2.html
            [3] => subcat3.html
            [4] => 
            [5] => 
            [6] => 
            [7] => sub_cat_slug7.html
            [8] => 
            [9] => sub_cat_slug9
        )

    [Item] => Array
        (
            [0] => item
            [1] => item1
            [2] => item2
            [3] => 
            [4] => item4
            [5] => 
            [6] => 
            [7] => 
            [8] => item8
            [9] => item9
        )


)
于 2013-06-14T02:58:35.810 回答
0

你可以试试这个:

preg_match('~/(?<main_cat>[^/\s]++/?+)(?<sub_cat>[^/\s]++/?+)?'
         . '(?>(?<filename>\S+?)\.html)?~', $url, $match);
print_r($match);

请注意,您可以使用命名的捕获轻松访问不同的部分(对于测试是否存在子模式很有用。)。

于 2013-06-14T08:00:53.640 回答