我正在匹配网址,所以我可以将请求连接到控制器/视图,并且有几个网址有多个选项,其中只有一个可以在网址中包含任何内容,但我还需要什么作为命名组后可用。
示例:
还有许多其他可能性,但这足以说明一个例子。基本上,如果网址以“新”结尾,则无法执行任何操作,而如果以“编辑”结尾,则还必须具有要编辑的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})))))?$
非常感谢任何提示/建议。
答案 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";
}