1

我正在匹配 url,所以我可以将请求连接到控制器/视图,并且有几个 url 有多个选项,其中只有一个可以在 url 后面有任何内容,但我还需要后面的内容可作为命名组使用。

例子:

  • /admin/某事#match
  • /admin/something/new #match
  • /admin/something/new/id #失败
  • /admin/something/edit #失败
  • /admin/something/edit/id #match

还有很多其他的可能性,但这足以作为一个例子。基本上,如果 url 以 'new' 结尾,什么都不能跟随,而如果它以 'edit' 结尾,它也必须有一个 id 才能编辑。

到目前为止我一直在使用的正则表达式:

^/admin/something(?:/(?P<action>new|edit(?:/(?P<id>\d{1,5}))))?$

空格爆炸版本:

^/admin/something(?:/
    (?P<action>
        new|        # create a new something
        edit(?:/    # edit an old something
                (?P<id>\d{1,5})    # id to edit
            )
        )
    )?    # actions on something are optional
$

但是如果 url 是“/admin/something/edit/id”,那么“action”组就是“edit/id”。我一直在控制器中使用一些字符串操作来将动作缩减为......动作,但我觉得积极的前瞻会更清晰。我只是无法让它发挥作用。

我一直在使用的前瞻正则表达式:(将匹配“新”,但不匹配“编辑”[带或不带 id])

^/admin/something(?:/(?P<action>new|edit(?=(?:/(?P<id>\d{1,5})))))?$

任何提示/建议将不胜感激。

4

4 回答 4

2

你的问题在于$最后。这是正则表达式匹配到行尾的零宽度断言。但是,您的前瞻也是一个零宽度断言(该 id 跟随编辑)。之所以称为前瞻,是因为它在前瞻内匹配,然后跳回到匹配的开头。所以它在 ...edit/id 上失败了,因为它试图断言 /id 在编辑之后并且/edit 是行尾。它仅在 ...edit 上失败,因为它试图断言 /id 跟随编辑。

有两种可能的解决方案。首先是简单地取出$。这可能是不可取的,因为它可能匹配 .../edit/id/gobbledygook。第二种解决方案是使用您的正则表达式语言重用捕获组的方法。我无法帮助您,因为我不知道您使用的是什么正则表达式。我不认识P<name>命名捕获的语法。你可以把你需要的任何东西放在<action>小组后面。

于 2009-07-28T02:43:35.067 回答
1
^/admin/something
(
    $               |
    /new$           |
    /edit/(\d{5})$
)
于 2009-07-28T02:48:30.580 回答
0

我得到的答案使用上述两个答案的部分来创建一个具有前瞻功能的正则表达式,该正则表达式还将我想要的所有值存储在命名组中,而没有额外的混乱,例如正斜杠。它符合我想要的一切,而其他一切都失败了。完美的。

^/admin/something(?:(?:/
                        (?P<action>
                            new$|
                            edit(?=/(?P<id>\d{1,5})$)
                        )
                    )|$)

我希望我可以将不止一个标记为答案,因为它们都帮助我找到了一条真正的道路。

于 2009-07-28T03:22:46.400 回答
0

非正则表达式方式,

$str = "/admin/something";
$s = explode("/",$str);
if ( end($s) == "something" || end($s) == "new" ){
    print "ok\n";
}
if ( strpos($str,"edit" )!==FALSE && is_numeric(end($s)) ){
    print "ok\n";
}
于 2009-07-28T03:57:49.000 回答