Phalcon 微应用程序路由正则表达式模式(除单词外的所有内容)

Phalcon micro app routes regex pattern (all except words)

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

我要获取id (f.e.)

url/foo/bar/baz/some123id

所以 id 可以是任何东西 countfind.

路径:

/count return 实体数

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

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

尝试过

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

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

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

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

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

我做错了什么?


解法:

编辑

解决方案 1:(mickmackusa)

解决方案 2:(我认为不完美)

/编辑

\/*((?!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

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

说明
(?<=.*\/) 正后视以获得斜杠
[^/]+ 一个或多个不是斜杠的字符
(?<!find|count) 负面回顾以确保它不是 'count' 或 'find'
$ 正则表达式结束

如果要匹配特定的 foo/bar 路径,则需要稍微替换一下正则表达式:
(?<=foo\/bar\/baz\/)[^/]+(?<!find|count)$

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

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

Phalcon-wrapped 模式:#^/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