尝试匹配这样的字符串:
/2011/10/Lorem-ipsum-dolor-it-amet-consectetur-adipisicing
/2011/10/Lorem-ipsum-dolor-it-amet-consectetur-adipisicing/
和
/2011/10/4545
/2011/10/4545/
获得年,月和第三部分。这是我得到的正则表达式:
%/(?P<year>\d{4})/(?P<month>\d{2})/((?P<id>\d{1,})|(?P<permalink>.{1,}))[/]{0,1}$%
我虽然得到的匹配数组总是包含3个变量:年,月和id或永久链接。但是会发生什么 - 如果永久链接匹配 - 我仍然会在结果数组中获得空id变量。有没有办法重写一个正则表达式,所以结果数组只包含年,月,id或永久链接?
答案 0 :(得分:4)
我认为使用|
语法时,命名组不会被“忽略”,因为无法知道是否要保留两个结果。换句话说,|
的两边都会被评估,即使其中一方有或没有匹配,与大多数编程语言中的条件or
不同。
例如,如果你有一个正则表达式
/(?P<foo>abc)|(?P<bar>def)/
并且要比较的字符串是abcdef
,在某些情况下,您希望知道两个子表达式匹配,因此应设置两个变量。如果在某些情况下设置了两个变量,最好在所有情况下设置它们,这样程序员就不必首先检查它们是否已经设置过处理它们。
作为对问题的评论“有没有办法重写正则表达式,因此生成的数组只包含年,月和id或永久链接”,为什么你想要这样?只需检查变量是否为空。如果正则表达式会将其中任何一个退出,您仍然需要检查它们中的哪一个已设置。完全相同的逻辑可用于检查哪些是空的。
答案 1 :(得分:1)
您不一定需要正则表达式。
$x = "/2011/10/4545";
$v = explode("/", $x);
$r = array_shift($v);
if(count($v) == 4){
array_pop($v);
print_r($v); }
输出
Array
(
[0] => 2011
[1] => 10
[2] => 4545
$url = "/2011/10/Lorem-ipsum-dolor-it-amet-consectetur-adipisicing";
$v = explode("/", $url);
array_shift($v);
array_pop($v);
if(count($v) == 3){
array_pop($v);
print_r($v);
} else {
print_r($v); }
输出
Array
(
[0] => 2011
[1] => 10
)
答案 2 :(得分:1)
由于它们存在于正则表达式中,因此命名组将始终包含在匹配组中,即使它们由于|
而未匹配任何内容。
您可能还想稍微改进正则表达式,用.
替换<permalink>
[^/]
,因为您不希望使用尾部斜杠(如果存在)作为固定链接。
然而,正如Mob所说,有一种更简单的方法可以解析这么简单的目标:
list($year, $target, $link) = array_slice(explode('/', $url), 1);
if (is_numeric($link)) {
// $link == id
}
else {
// $link == permalink
}