我迷失了phalcon正则表达式路线模式。
我想获得id(f.e。)
url/foo/bar/baz/some123id
所以id
可以是,但 count
和find
。
路径:
/count
返回实体计数
/find
按查询查找实体(?foo = 123& ...)
/{id}
通常按ID搜索(不起作用)
试过
/{id:[^count|find]*}
不适用于/123c
(c在"计数")
尝试使用在线正则表达式解决此问题:
/{id:^(?!^count$|^find$).+}
按预期工作。见https://regex101.com/r/jC8nB0/230
但如果我在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
答案 0 :(得分:1)
如果您想取消特定子字符串的资格,(*SKIP)(*FAIL)
是一种方便的技巧。取消资格count
和find
后,您可以使用[^/\r\n\t]+
匹配任意数量的有效字符。
原始模式:/foo/bar/+(?:(?:find|count)/*$(*SKIP)(*FAIL)|([^/\r\n\t]+))/*
Phalcon包裹的模式:#^/foo/bar/+(?:(?:find|count)/*$(*SKIP)(*FAIL)|([^/\r\n\t]+))/*$#u
模式细分:
# // 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)$