我有以下链接结构:
/type1
/type2
/type3
这些链接对应于网站的默认语言。不幸的是,客户端并不想在URL前面添加默认语言以保持一致性,因此只有其他语言才会有以下URL:
/en
/en/type1
/de/type2
/de
/fr/type3
/fr
还有很多其他变量,但只有这部分是动态的。我的正则表达式开始如下:
(en|de|fr)?\/?(type1|type2|type3)?\/?
这基本上意味着捕获语言(如果存在),然后捕获页面(如果存在)。但是它执行的匹配比所需要的多得多,并且还会捕获空字符串等。
我试图找出如何捕获所有这些选项:
/en
/en/type1
/type1
在一个表达式中,当然如果可能的话。如何才能使这两个组中的一组成为必需,所以基本上URL既有两个,也有其中一个,但从来没有?我结合前瞻查看了反向引用,但我认为我在这里错过了一些重要信息...
我希望保留这些群组,以便group1 = language
和group2 = page
答案 0 :(得分:0)
我想不出用一个正则表达式做你想要的方法。但是,另一种可能性是使用单个正则表达式来匹配您想要的匹配 URL模式。然后,使用简短的PHP脚本来提取语言(如果存在)和页面:
$path = "/de/type1";
if (preg_match("/^(?:\/(?:en|de|fr))?(?:\/(?:type1|type2|type3))?$/i", $path, $match)) {
$parts = preg_split("/\//", $path);
if (sizeof($parts) == 3) {
echo "language: " . $parts[1] . ", page: " . $parts[2];
}
else {
if (preg_match("/^(?:en|de|fr)$/i", $parts[1], $match)) {
echo "language: " . $parts[1] . ", page:";
}
else {
echo "language: default, page: " . $parts[1];
}
}
}
这是我用来匹配的模式:
^(?:/(?:en|de|fr))?(?:/(?:type1|type2|type3))?$
它允许/(type1|type2|type3)
,可选地以语言路径开头。
答案 1 :(得分:0)
这个会给你一个或者另一个(以先到者为准),但不要求如果你提供两者,它们是匹配的(例如你可以指定/ en / type3,它会给你/ en ):
<?php
$pat = '~(/(?:en|de|fr)\b|/type\d\b)~';
$test = ['/en', '/type1', '/en/type1', '/en/type3', '/english/type1'];
foreach ($test as $t) if (preg_match($pat, $t, $match)) echo "'{$t}' = '{$match[1]}'\n";
?>
这给了你:
'/en' = '/en'
'/type1' = '/type1'
'/en/type1' = '/en'
'/en/type3' = '/en'
'/english/type1' = '/type1'
(最后一个例子是为了说明为什么你需要模式中的\ b)