Zend路由正则表达式,可选参数

时间:2013-11-25 10:12:57

标签: php regex zend-framework zend-route

我需要一些关于我在Zend(Zend1)中的路线的帮助...

我需要我可以使用我的路线:

http://mywebsite.com/myfolder/region/job/   
http://mywebsite.com/myfolder/region/job/add  
http://mywebsite.com/myfolder/region/job/add/page  
http://mywebsite.com/myfolder/region/job/page   

参数添加页面是可选的...

这就是我做的事情

$route = new Zend_Controller_Router_Route_Regex(
          'myfolder/([^/]+)/([^/]+)/?([^/]+)?/?([0-9]+)?',
          array('controller'    => 'myfolder','action'  => 'search'), 
          array(1 => 'region',2 => 'job', 3 => 'add', 4 => 'page'), 
          'myfolder/%s/%s/%s/%s'
         ); 

显然,它不起作用...... 我想要的是?我希望最后两个参数(添加页面)是可选的...

你能帮帮我吗?我的正则表达式有什么问题?

编辑1:

好的,所以我试了一下,但还不行...... 我需要参数添加页面是可选的...

    $route = new Zend_Controller_Router_Route(
'myfolder/:region/:job/:add/:page',
array(
    'controller'    => 'myfolder',
    'action'        => 'search',
    'region'        => 'XX',
    'job'        => '',
    'add'    => '',
    'page'      => 1
),
array(
    'region' => '[a-zA-Z-_0-9-]+',
    'job' => '[a-zA-Z-_0-9-]+',
    'add' => '[a-zA-Z-_]+',
    'page' => '\d+'
)
);  

这样,这个http://mywebsite.com/myfolder/region/job/page不起作用......

编辑2:

我也试过了'myfolder/:region/:job/*',但结果是一样的,不能按我的意愿行事...... 我真的很想知道是否有可能......

编辑3: ##

$route = new Zend_Controller_Router_Route_Regex('myfolder/([^/]+)/([^/]+)(?:/|$)(?:(?!\d+(?:/|$))([^/]+)(?:/|$))?(?:(\d+)(?:/|$))?$',
      array('controller'    => 'myfolder', 'action' => 'recherche', 'presta' => ''), 
      array(1 => 'region',2 => 'job', 3 => 'presta', 4 => 'page'), 
      'myfolder/%s/%s/%s/%s');

1 个答案:

答案 0 :(得分:2)

准备好自己。

RegEx

myfolder/([^/]+)/([^/]+)(?:/|$)(?:(?!\d+(?:/|$))([^/]+)(?:/|$))?(?:(\d+)(?:/|$))?$

See it working on RegExr(在RegExr上,我必须将\n\r添加到其中一个否定的类中,因此它与我的所有换行符都不匹配,实际上你可能不会处理换行符虽然。)

RegExr需要注意的重要一点是,在第四种情况下,页码位于第四个捕获组中,第三组中没有任何内容。

说明

myfolder/([^/]+)/([^/]+)所有看起来都很好,没有变化。

(?:/|$)匹配/或输入结束。

接下来,总的来说,我们有一个非可选的非捕获组。这将是add部分。

(?:(?!\d+(?:\|$))([^/]+)(?:/|$))?

现在让我们进一步分解:

(?!\d+(?:/|$))确保它不是页码 - 数字后跟/或输入结束。 (否定前瞻)

([^/]+)我们的捕获组 - 示例中的add

(?:/|$)匹配/或输入结束。

现在我们的页码组,它是可选的和非捕获的:

(?:(\d+)(?:/|$))?捕获数字,然后再次匹配/或输入结束。

$以防万一它试图匹配实际匹配的子串,我扔进了输入锚的另一端(因为你可以根据需要连续匹配),尽管没有它的正则表达式函数


生成路径

你基本上想要的是一种方法:

目前第二和第三个参数是:

array(1 => 'region',2 => 'job', 3 => 'add', 4 => 'page'), 
'myfolder/%s/%s/%s/%s'

你希望它们像:

array(1 => 'region',2 => 'job', 3 => '/'+'add', 4 => '/'+'page'), 
'myfolder/%s/%s%s%s'

如果存在可选组,则只添加/。上面的代码不起作用,但也许有一些方法可以实现它。