代码之家  ›  专栏  ›  技术社区  ›  nilamo

选项组中的regex lookahead

  •  1
  • nilamo  · 技术社区  · 15 年前

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

    实例:

    • /管理员/匹配的内容
    • /管理/某物/新匹配
    • /管理员/某物/新的/id# 失败
    • /管理/某物/编辑# 失败
    • /admin/something/edit/id匹配

    还有很多其他的可能性,但这对于一个例子来说已经足够好了。基本上,如果url以“new”结尾,则没有任何内容可以遵循,而如果以“edit”结尾,则还必须具有要编辑的ID。

    到目前为止我一直使用的regex:

    ^/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”。我在控制器中使用了一点字符串manip来减少动作…行动,但我觉得积极向前看会更干净。我只是没能让它发挥作用。

    我一直在使用的lookahead regex:(将匹配“new”,但不匹配“edit”[有或没有ID])

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

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

    4 回复  |  直到 12 年前
        1
  •  2
  •   Sean    15 年前

    你的问题在于 $ 最后。这是一个 zero-width assertion 正则表达式与行尾匹配。然而,你的 lookahead 零宽度断言(该ID跟随编辑)。之所以称为先行,是因为它在先行中匹配,然后跳回到该匹配的开头。所以它在…edit/id上失败了,因为它试图断言/id跟在edit后面 /编辑是行尾。它在…单独编辑时失败,因为它试图断言/id跟随编辑。

    有两种可能的解决方案。首先是简单地取出美元。这可能不可取,因为它可以匹配…/edit/id/gobbledygook。第二个解决方案是使用regex语言的方法重用捕获的组。我不能帮你,因为我不知道你在用什么瑞格。我不认识 P<name> 命名捕获的语法。你会把你需要的东西放在 <action> 组。

        2
  •  1
  •   FMc TLP    15 年前
    ^/admin/something
    (
        $               |
        /new$           |
        /edit/(\d{5})$
    )
    
        3
  •  0
  •   ghostdog74    15 年前

    非正则表达式,

    $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";
    }
    
        4
  •  0
  •   ashwnacharya    15 年前

    我得到的答案使用上述两个答案中的一部分来创建一个具有lookahead的regex,它还将我想要的所有值存储在命名组中,而不需要像正斜杠这样的额外混乱。它符合我想要的一切,但失败了其他一切。很完美。

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

    我希望我能将多个标记为 这个 回答,因为他们都帮助我找到了一条真正的路。