选项组中的正则表达式预测

时间:2009-07-28 02:24:42

标签: regex regex-lookarounds

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

示例:

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

还有许多其他可能性,但这足以说明一个例子。基本上,如果网址以“新”结尾,则无法执行任何操作,而如果以“编辑”结尾,则还必须具有要编辑的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
$

但是如果网址是'/ admin / something / edit / id',则'action'组是'edit / id'。我一直在控制器中使用一点点字符串操作来减少动作只是...动作,但我觉得一个积极的前瞻会更清洁。我只是无法让它工作。

我一直在研究的前瞻性正则表达式:(将匹配'new',但不是'edit'[有或没有id])

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

非常感谢任何提示/建议。

4 个答案:

答案 0 :(得分:2)

你的问题在于最后的$。这是正则表达式与行尾相匹配的zero-width assertion。但是,您的lookahead 也是零宽度断言(该ID跟随编辑)。它被称为前瞻的原因是因为它在前瞻中匹配,然后跳回到该匹配的开头。所以它失败了...编辑/ id因为它试图断言/ id跟随编辑并且 / edit是该行的结尾。它失败了...单独编辑,因为它试图断言/ id跟随编辑。

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

答案 1 :(得分:1)

^/admin/something
(
    $               |
    /new$           |
    /edit/(\d{5})$
)

答案 2 :(得分:0)

我来到的答案使用了上​​述两个答案中的部分来创建一个带有前瞻的正则表达式,该正则表达式还存储了我想要在命名组中的所有值,而没有额外的混乱,例如正斜杠。它匹配我想要的一切,并失败了一切。完美。

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

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

答案 3 :(得分: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";
}