Phalcon微应用程序路由正则表达式模式(除了单词之外)

时间:2018-02-19 15:12:28

标签: php regex path routes phalcon

我迷失了phalcon正则表达式路线模式。

我想获得id(f.e。)

url/foo/bar/baz/some123id

所以id可以是,但 countfind

路径:

/count 返回实体计数

/find 按查询查找实体(?foo = 123& ...)

/{id} 通常按ID搜索(不起作用)

试过

/{id:[^count|find]*}不适用于/123c(c在"计数")

尝试使用在线正则表达式解决此问题:

/{id:^(?!^count$|^find$).+}

按预期工作。见https://regex101.com/r/jC8nB0/230

enter image description here

但如果我在phalcon路线中使用这个正则表达式,它根本不起作用。

我做错了什么?

解决方案:

修改

解决方案1:https://stackoverflow.com/a/49123320/3411766(mickmackusa)

解决方案2 :(我觉得不完美)

/ EDIT

\/*((?!count$|find$)[^\/\r\n\t]+)\/*

为什么:

我检查了phalcon用作编译模式的内容:

foreach ($app->getRouter()->getRoutes() as $route) {
    file_put_contents('tmp/_test.log', var_export($route->getCompiledPattern(), true) . PHP_EOL, FILE_APPEND);
}

/{id:^(?!^count$|^find$).+}

成为了

#^/^(?!^count$|^find$).+$#u

我认为 Leyff da 提到^是问题所在。

/foo/bar/路径示例:

/foo/bar/{id:\/*((?!count$|find$)[^\/\r\n\t]+)\/*}

变为

#^\/foo\/bar\/\/*((?!count$|find$)[^\/\r\n\t]+)\/*$#u

模式分解:

#                                       delimiter
    ^                                   start of string
        \/foo\/bar\/                    path
        \/*                             possible multiple slashes before id like "foo/bar///id123"
            (                           capture id
                (
                    ?!                  negative lookahead
                    count               string
                        $               end of string (to not match f.e. counts, count1, ...)
                    |                   or
                    find                string
                        $               end of string (to not match f.e. finds, find1, ...)
                )
                [^\/\r\n\t]+            do not capture slashes, tab or new line after id
            )
        \/*                             possible multiple slashes after id like "foo/bar/id123///"
    $                                   end of string
#                                       delimiter
u                                       unicode

2 个答案:

答案 0 :(得分:1)

如果您想取消特定子字符串的资格,(*SKIP)(*FAIL)是一种方便的技巧。取消资格countfind后,您可以使用[^/\r\n\t]+匹配任意数量的有效字符。

原始模式:/foo/bar/+(?:(?:find|count)/*$(*SKIP)(*FAIL)|([^/\r\n\t]+))/*

Phalcon包裹的模式:#^/foo/bar/+(?:(?:find|count)/*$(*SKIP)(*FAIL)|([^/\r\n\t]+))/*$#u

Pattern Demo

模式细分:

#                                    // pattern starting delimiter
^                                    // match start of the string
/foo/bar                             // literally match /foo/bar
/+                                   // match (as much as possible) one or more forward slashes
(?:                                  // start a non-capturing group (to maintain pattern logic/intent)
    (?:find|count)/*$(*SKIP)(*FAIL)  // match the words: find or count followed immediately by zero or more forward slashes then the end of the string ...if a match force then entire string to fail
    |                                // or
    ([^/\r\n\t]+)                    // capture one or more (as much as possible) characters that are not: forward slash, line return, newline, tab
)                                    // end non-capturing group
/*                                   // match zero or more forward slashes
$                                    // match the end of the string
#                                    // pattern ending delimiter
u                                    // pattern modifier: allow unicode characters

答案 1 :(得分:0)

这里的问题是^,它是字符串的开头,而不是匹配的正则表达式的开头。然后somthing^something无法匹配 解决方案:(?<=.*\/)[^/]+(?<!find|count)$

解释
(?<=.*\/)获得斜线的正面看法 [^/]+一个或多个不是斜线的字符
(?<!find|count)负面的背后隐藏,以确保它不会计数&#39;或者&#39;找到&#39;
$正则表达式结束

如果要在需要更换正则表达式之前匹配特定的foo/bar路径:
(?<=foo\/bar\/baz\/)[^/]+(?<!find|count)$