Php 解析前后没有特定字符的参数模式
为了练习,我正在创建自己的PHP路由器。此路由器可以接受如下指定的参数: {i:variableName}Php 解析前后没有特定字符的参数模式,php,regex,Php,Regex,为了练习,我正在创建自己的PHP路由器。此路由器可以接受如下指定的参数: {i:variableName} i代表参数类型(在本例中为整数),而variableName代表variableName 单个路由URI可能如下所示: /home/{i:id}-{s:noVar}/{m:varName}/{s:someOther} 为此,我创建了以下正则表达式模式: [^{}]*({((?<type>\D):)?(?<name>[a-zA-Z_-ÿ][a-zA-Z0-9_-ÿ]+
i
代表参数类型(在本例中为整数),而variableName
代表variableName
单个路由URI可能如下所示:
/home/{i:id}-{s:noVar}/{m:varName}/{s:someOther}
为此,我创建了以下正则表达式模式:
[^{}]*({((?<type>\D):)?(?<name>[a-zA-Z_-ÿ][a-zA-Z0-9_-ÿ]+)})[^{}]*
这方面的一个例子是,我将无法做以下事情:
/home/{i:id}{s:noVar}/{m:varName}{s:someOther}
它们之间需要有字符
我认为这段正则表达式可以做到,“不要包含零个或多个{
或}
字符
当我在像/home/{I:id}{s:noVar}/{m:varName}/{s:someOther}
这样的模式上运行这个正则表达式时,它仍然检索所有参数,甚至是相邻的参数
这是怎么可能的?我如何使正则表达式只检索彼此不相邻的参数?我建议匹配2个或更多连续的
{…}
块并忽略这些匹配,而只处理所有其他{…}
(非相邻)块。使用众所周知的PCRE:
(?:{(?[a-zA-Z]:)?[a-zA-Z]\w*}{2,}(*SKIP)(*F){(?:(?[a-zA-Z]):)(?[a-zA-Z]\w*}
见
说明:
-正则表达式中与下面解释的模式(仅不包括捕获组)匹配的第一个可选分支,该模式连续出现,请参见(?:{(?[a-zA-Z]:)?[a-zA-Z_uw*}{2,}(*SKIP)(*F)
,这意味着在一段时间内匹配两个或多个实例。{2,
谓词使正则表达式引擎忽略此匹配并继续(*SKIP)(*FAIL)
-或符合我们的需要:|
-打开的{
{
-与ASCII字母(捕获到组“type”)和(?:(?[a-zA-Z]):)?
匹配的可选组:
-将“名称”分组以捕获ASCII字母或(?[a-zA-Z]\w*)
(请参见
,后跟0+字字符(来自[a-zA-Z]
范围)[a-zA-Z0-9\
-关闭}
}
(?和(?!{)括起您的第一个图案
.See@WiktorStribiżew你是什么意思?我还是正则表达式的初学者。你知道-ÿ
创建了一个范围吗?这是你的意图吗?@WiktorStribiżew这是一个变量名,我基本上是在谷歌上搜索的。我猜这已经脱离主题了,但它到底做了什么?我不明白一点:I:
really可选?检查是否对您有效。这只是变得更复杂了,感谢您的解释。一旦您了解了模式匹配的内容,就不难了。起初,有(?和(?!{)
,它们现在在哪里?您在完整正则表达式开头编写的内容是否相同?请阅读我在答案中的解释。我们匹配连续的{}
块,然后丢弃它们。只有匹配的块是独立的块。如果我们使用lookback(?)和lookahead(?!{)
我们还将排除{}
块前面紧跟}
或后面紧跟{
。并且没有保证那里有一个完整的块。我们可以在一个块之后检查一个块,但是我们不能在一个块之前检查一个块。当然,如果您确定块的周围将只有{}
,您可以使用环视方法。
[^{}]*
(?:{(?:[a-zA-Z]:)?[a-zA-Z_]\w*}){2,}(*SKIP)(*F)|{(?:(?<type>[a-zA-Z]):)?(?<name>[a-zA-Z_]\w*)}