如何编写递归匹配RESTful路径的正则表达式?

时间:2017-02-23 16:54:01

标签: php regex pcre restful-url symfony-routing

Regexp不是我的力量,如果有可能的话,我想在这个方面提供一些帮助:

我需要创建一个递归匹配RESTful路径的正则表达式。目的是创建与此正则表达式匹配的Symfony路由。以下是RESTful路径的一些示例:

/resources
/resources/123
/resources/123/children-resources
/resources/123/children-resources/123
/resources/123/children-resources/123/grandchildren-resources

等等......

基本上,我希望这种模式在一次或多次无限期地重复:

^\/[a-z]+(\-[a-z]+)*(\/[0-9]+)?$

请注意,要访问子资源,必须存在父资源的标识符。

我在这里列出了一个简单的单元测试列表(仅用于启动两级路径): https://regex101.com/r/Hxg0m4/2/tests

我搜索了同一主题的问题,但没有一个与我的问题真正相关。我还在上面的正则表达式上尝试了一些修改 - 比如在正则表达式的末尾使用+符号,或者使用(?R) ...它从未通过我的单元测试。

任何帮助都将很高兴。

P.S:这是我关于stackoverflow的第一个问题,请不要犹豫,告诉我如何更好地表达我的问题。

1 个答案:

答案 0 :(得分:3)

这种递归模式应该有效:

^(\/[a-z]+(?:-[a-z]+)*(?:$|\/\d+(?:$|(?1))))

说明:

^                       // assert start of string
(
    \/                  // start with a slash
    [a-z]+(?:-[a-z]+)*  // followed by a word
    (?:                 // then, either:
        $               // end of string
    |                   // or:
        \/              // a slash
        \d+             // followed by digits
        (?:             // then, either:
            $           // end of string
        |               // or:
            (?1)        // recurse the entire pattern (except the start of string anchor)
        )
    )
)