练习我创建自己的PHP路由器。此路由器可以接收如下指定的参数:
{I:VARIABLENAME}
i
代表参数类型(在本例中为整数),variableName
代表变量名。
单个路由URI可能如下所示:
/家庭/ {I:ID} - {S:傲华尔} / {M:的varName} / {S:一些其它}
我为此目的创建了以下正则表达式模式:
[^{}]*({((?<type>\D):)?(?<name>[a-zA-Z_-ÿ][a-zA-Z0-9_-ÿ]+)})[^{}]*
由于没有2个参数彼此相邻,并且旁边有一个字符,我用这个部分展开了正则表达式:
[^{}]*
这方面的一个例子是我无法做到这样的事情:
/家庭/ {I:ID} {S:傲华尔} / {M:的varName} {S:一些其它}
它们之间需要有字符。
我认为这段正则表达式会做,&#34;不要包含零个或多个{
或}
字符。
当我在/home/{i:id}{s:noVar}/{m:varName}/{s:someOther}
这样的模式上运行此正则表达式时,它仍会检索所有参数,甚至是彼此相邻的参数。
这怎么可能?我怎样才能使正则表达式只检索彼此不相邻的参数?
答案 0 :(得分:1)
我建议匹配2个或更多连续的{...}
块并忽略这些匹配,并且只处理所有其他{...}
(非相邻)块。使用着名的PCRE (*SKIP)(*F)
technique:
(?:{(?:[a-zA-Z]:)?[a-zA-Z_]\w*}){2,}(*SKIP)(*F)|{(?:(?<type>[a-zA-Z]):)?(?<name>[a-zA-Z_]\w*)}
请参阅regex demo
<强>解释强>:
(?:{(?:[a-zA-Z]:)?[a-zA-Z_]\w*}){2,}(*SKIP)(*F)
- 正则表达式中第一个替代分支(2)与下面解释的模式(只是没有捕获组)相匹配,连续出现,请参阅{2,}
表示匹配一次发生2次或更多次。 (*SKIP)(*FAIL)
动词使正则表达式引擎省略此匹配并继续。|
- 或匹配我们需要的内容:{
- 开放{
(?:(?<type>[a-zA-Z]):)?
- 与ASCII字母匹配的可选组(捕获到组&#34;类型&#34;)和:
(?<name>[a-zA-Z_]\w*)
- Group&#34; name&#34;捕获ASCII字母或_
(参见[a-zA-Z_]
后跟0 +字符(来自[a-zA-Z0-9_]
范围)}
- 关闭}