我正在为我正在处理的基于PHP的大型网站开发一个请求路由器,但是我在试图为我的路由使用自定义表达式时遇到困难。
虽然我知道有预先制作的替代品和路由器可以让我的生活更轻松,并且具有相同的功能(事实上,我一直在寻找他们的源代码来尝试解决这个问题),我是仍然是一个编程学生,学习如何创建我自己只能是一件好事!
示例:
以下是我的一个路线表达式的示例:
<protocol (https?)>://<wildcard>.example.com/<controller>/{<lang=en (en|de|pl)>/}<name ([a-zA-Z0-9_-]{8})>
这可以同样匹配其中任何一个:
http://www.example.com/test/en/hello_123
https://subdomain.example.com/another_test/hello_45
给我一个很好的,方便的数组(对于后者):
array(
'protocol' => 'http',
'wildcard' => 'subdomain',
'controller' => 'another_test',
'lang' => 'en',
'name' => "hello_45"
)
我还可以首先包含一个数组,其默认值将被路由器找到的值覆盖。因此,举例来说,我可以省略<controller>
变量,只需编写test
,然后使用数组,添加"controller"=>"test"
。
以下是规则:
<>
之间的任何内容都是变量。转义\<\>
将被忽略,即使介于两者之间。 URL中的区域匹配应保存到结果数组中,变量名称为键。{}
将某个部分标记为可选,并且永远不能内部变量<>
。它们之间的任何内容都可以在目标中被忽略 - 但是,如果为中间的任何变量指定了默认值,则必须将该变量添加到结果数组中,使用名称作为键,并使用默认值作为值。转义大括号将被忽略。=
之后,例如<name=default>
。()
括起来。当然,会忽略转义括号。<controller>
替换([\/]+)
,但之后我必须使用数组为它设置一个值。 我尝试过的事情:
我一直在阅读我能找到的每个路由器的源代码。
到目前为止,我已经做了几个讨厌的小正则表达式,但我意识到我完全混淆了如何将它们聚合并扩展它们。
这与括号相符,忽略转义的括号:{([^{\\]*(?:\\.[^}\\]*)*)}
这匹配一个变量,有或没有默认值:<([^<\\]*(?:\\.[^>\\]*)*)(?:=?([^<>\\]*))>
这是一种不圣洁的地狱,其中的一些让我写这篇文章:<([^<\\]*(?:\\.[^>\\]*)*)(?:=?([^<>\\]*))(?: ?)(\([^{}<>\(\)\\]+\))?>
(但它确实匹配变量和正则表达式部分。)
有人可以从提供类似功能的库中提供任何提示,甚至示例源代码吗?如果这对我自己编码几乎是不可能的,那么有一个足够好的库吗?
答案 0 :(得分:1)
如果您要尝试匹配域,this regex101 demo应该将这些部分与名为的各个部分匹配。
另一方面,如果您尝试匹配路由表达式,this other regex101 demo能够解析您目前指定的令牌。
我可能错过了一些规范,但您可以随时留下反馈并解释它的不足之处(甚至更新该网站上的正则表达式并保存更新的版本)。